aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Le Cuirot <james.le-cuirot@yakara.com>2015-03-18 15:15:05 +0000
committerJames Le Cuirot <james.le-cuirot@yakara.com>2018-10-29 15:11:35 +0000
commitcf1d75d95d06ce3ac9e3ab7f19ecc17b49530942 (patch)
treefdb7c6f84f92f5f90bf346447ea5d5dce277e466
parent0d68e0690f449bf815c975c25d4d74917d3cad11 (diff)
downloadrails-cf1d75d95d06ce3ac9e3ab7f19ecc17b49530942.tar.gz
rails-cf1d75d95d06ce3ac9e3ab7f19ecc17b49530942.tar.bz2
rails-cf1d75d95d06ce3ac9e3ab7f19ecc17b49530942.zip
Avoid violating key constraints in fixture HABTM associations
When loading fixtures, Ruby 1.9's hash key ordering means that HABTM join table rows are always loaded before the parent table rows, violating foreign key constraints that may be in place. This very simple change ensures that the parent table's key appears first in the hash. Violations may still occur if fixtures are loaded in the wrong order but those instances can be avoided unlike this one.
-rw-r--r--activerecord/lib/active_record/fixture_set/table_rows.rb3
-rw-r--r--activerecord/test/cases/fixtures_test.rb4
2 files changed, 7 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/fixture_set/table_rows.rb b/activerecord/lib/active_record/fixture_set/table_rows.rb
index e8335a2e10..3e3c0bc7ab 100644
--- a/activerecord/lib/active_record/fixture_set/table_rows.rb
+++ b/activerecord/lib/active_record/fixture_set/table_rows.rb
@@ -45,6 +45,9 @@ module ActiveRecord
# track any join tables we need to insert later
@tables = Hash.new { |h, table| h[table] = [] }
+ # ensure this table is loaded before any HABTM associations
+ @tables[table_name] = nil
+
build_table_rows_from(fixtures, config)
end
diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb
index 82ca15b415..1092b9553f 100644
--- a/activerecord/test/cases/fixtures_test.rb
+++ b/activerecord/test/cases/fixtures_test.rb
@@ -619,6 +619,10 @@ class HasManyThroughFixture < ActiveRecord::TestCase
assert_equal load_has_and_belongs_to_many["parrots_treasures"], rows["parrot_treasures"]
end
+ def test_has_and_belongs_to_many_order
+ assert_equal ["parrots", "parrots_treasures"], load_has_and_belongs_to_many.keys
+ end
+
def load_has_and_belongs_to_many
parrot = make_model "Parrot"
parrot.has_and_belongs_to_many :treasures