aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/CHANGELOG2
-rwxr-xr-xactiverecord/lib/active_record/fixtures.rb32
-rw-r--r--activerecord/test/fixtures/categories_ordered.yml7
-rwxr-xr-xactiverecord/test/fixtures_test.rb13
4 files changed, 50 insertions, 4 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index ae9e5668be..7fc4162bcc 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,5 @@
*SVN*
-=======
+* YAML fixtures support ordered hashes for fixtures with foreign key dependencies in the same table. #1896 [purestorm@ggnore.net]
* :dependent now accepts :nullify option. Sets the foreign key of the related objects to NULL instead of deleting them. #2015 [Robby Russell <robby@planetargon.com>]
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index 11a53387f9..e0b713fb83 100755
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -38,6 +38,20 @@ end
# indented list of key/value pairs in the "key: value" format. Records are separated by a blank line for your viewing
# pleasure.
#
+# Note that YAML fixtures are unordered. If you want ordered fixtures, use the omap YAML type. See http://yaml.org/type/omap.html
+# for the specification. You will need ordered fixtures when you have foreign key constraints on keys in the same table.
+# This is commonly needed for tree structures. Example:
+#
+# --- !omap
+# - parent:
+# id: 1
+# parent_id: NULL
+# title: Parent
+# - child:
+# id: 2
+# parent_id: 1
+# title: Child
+#
# = CSV fixtures
#
# Fixtures can also be kept in the Comma Separated Value format. Akin to YAML fixtures, CSV fixtures are stored
@@ -293,8 +307,12 @@ class Fixtures < YAML::Omap
if File.file?(yaml_file_path)
# YAML fixtures
begin
- yaml = YAML::load(erb_render(IO.read(yaml_file_path)))
- yaml.each { |name, data| self[name] = Fixture.new(data, @class_name) } if yaml
+ if yaml = YAML::load(erb_render(IO.read(yaml_file_path)))
+ yaml = yaml.value if yaml.kind_of?(YAML::Syck::PrivateType)
+ yaml.each do |name, data|
+ self[name] = Fixture.new(data, @class_name)
+ end
+ end
rescue Exception=>boom
raise Fixture::FormatError, "a YAML error occured parsing #{yaml_file_path}. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Please have a look at http://www.yaml.org/faq.html\nThe exact error was:\n #{boom.class}: #{boom}"
end
@@ -350,7 +368,15 @@ class Fixture #:nodoc:
end
def initialize(fixture, class_name)
- @fixture = fixture.is_a?(Hash) ? fixture : read_fixture_file(fixture)
+ case fixture
+ when Hash, YAML::Omap
+ @fixture = fixture
+ when String
+ @fixture = read_fixture_file(fixture)
+ else
+ raise ArgumentError, "Bad fixture argument #{fixture.inspect}"
+ end
+
@class_name = class_name
end
diff --git a/activerecord/test/fixtures/categories_ordered.yml b/activerecord/test/fixtures/categories_ordered.yml
new file mode 100644
index 0000000000..294a6368d6
--- /dev/null
+++ b/activerecord/test/fixtures/categories_ordered.yml
@@ -0,0 +1,7 @@
+--- !omap
+<% 100.times do |i| %>
+- fixture_no_<%= i %>:
+ id: <%= i %>
+ name: <%= "Category #{i}" %>
+ type: Category
+<% end %>
diff --git a/activerecord/test/fixtures_test.rb b/activerecord/test/fixtures_test.rb
index f51de4a6d1..ae45a9f251 100755
--- a/activerecord/test/fixtures_test.rb
+++ b/activerecord/test/fixtures_test.rb
@@ -155,6 +155,19 @@ class FixturesTest < Test::Unit::TestCase
def test_empty_csv_fixtures
assert_not_nil Fixtures.new( Account.connection, "accounts", File.dirname(__FILE__) + "/fixtures/naked/csv/accounts")
end
+
+ def test_omap_fixtures
+ assert_nothing_raised do
+ fixtures = Fixtures.new(Account.connection, 'categories', File.dirname(__FILE__) + '/fixtures/categories_ordered')
+
+ i = 0
+ fixtures.each do |name, fixture|
+ assert_equal "fixture_no_#{i}", name
+ assert_equal "Category #{i}", fixture['name']
+ i += 1
+ end
+ end
+ end
end