Skip to content

Commit 53df1e1

Browse files
authored
Merge pull request rails#47671 from alpaca-tc/references_with_deferrable_foreign_key
deferrable foreign key can be passed to references
2 parents 83d9e44 + ec0a2a9 commit 53df1e1

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

activerecord/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
* The deferrable foreign key can be passed to `t.references`.
2+
3+
*Hiroyuki Ishii*
4+
15
* Deprecate `deferrable: true` option of `add_foreign_key`.
26

37
`deferrable: true` is deprecated in favor of `deferrable: :immediate`, and

activerecord/lib/active_record/connection_adapters/postgresql/schema_creation.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ def visit_AddForeignKey(o)
2323
end
2424
end
2525

26+
def visit_ForeignKeyDefinition(o)
27+
super.dup.tap do |sql|
28+
sql << " DEFERRABLE INITIALLY #{o.deferrable.to_s.upcase}" if o.deferrable
29+
end
30+
end
31+
2632
def visit_CheckConstraintDefinition(o)
2733
super.dup.tap { |sql| sql << " NOT VALID" unless o.validate? }
2834
end

activerecord/test/cases/migration/references_foreign_key_test.rb

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,48 @@ class ReferencesForeignKeyInCreateTest < ActiveRecord::TestCase
6262
assert_equal([["testings", "testing_parents", "parent_id"]],
6363
fks.map { |fk| [fk.from_table, fk.to_table, fk.column] })
6464
end
65+
66+
if current_adapter?(:PostgreSQLAdapter)
67+
test "deferrable: false option can be passed" do
68+
@connection.create_table :testings do |t|
69+
t.references :testing_parent, foreign_key: { deferrable: false }
70+
end
71+
72+
fks = @connection.foreign_keys("testings")
73+
assert_equal([["testings", "testing_parents", "testing_parent_id", false]],
74+
fks.map { |fk| [fk.from_table, fk.to_table, fk.column, fk.deferrable] })
75+
end
76+
77+
test "deferrable: :immediate option can be passed" do
78+
@connection.create_table :testings do |t|
79+
t.references :testing_parent, foreign_key: { deferrable: :immediate }
80+
end
81+
82+
fks = @connection.foreign_keys("testings")
83+
assert_equal([["testings", "testing_parents", "testing_parent_id", :immediate]],
84+
fks.map { |fk| [fk.from_table, fk.to_table, fk.column, fk.deferrable] })
85+
end
86+
87+
test "deferrable: :deferred option can be passed" do
88+
@connection.create_table :testings do |t|
89+
t.references :testing_parent, foreign_key: { deferrable: :deferred }
90+
end
91+
92+
fks = @connection.foreign_keys("testings")
93+
assert_equal([["testings", "testing_parents", "testing_parent_id", :deferred]],
94+
fks.map { |fk| [fk.from_table, fk.to_table, fk.column, fk.deferrable] })
95+
end
96+
97+
test "deferrable and on_(delete|update) option can be passed" do
98+
@connection.create_table :testings do |t|
99+
t.references :testing_parent, foreign_key: { on_update: :cascade, on_delete: :cascade, deferrable: :immediate }
100+
end
101+
102+
fks = @connection.foreign_keys("testings")
103+
assert_equal([["testings", "testing_parents", "testing_parent_id", :cascade, :cascade, :immediate]],
104+
fks.map { |fk| [fk.from_table, fk.to_table, fk.column, fk.on_delete, fk.on_update, fk.deferrable] })
105+
end
106+
end
65107
end
66108
end
67109
end

0 commit comments

Comments
 (0)