From da675e536df785596645dce0d5cd5c7817af39e4 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sat, 15 Oct 2005 02:01:38 +0000 Subject: Support ordered YAML fixtures. #1896 git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@2600 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activerecord/CHANGELOG | 2 +- activerecord/lib/active_record/fixtures.rb | 32 ++++++++++++++++++++--- activerecord/test/fixtures/categories_ordered.yml | 7 +++++ activerecord/test/fixtures_test.rb | 13 +++++++++ 4 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 activerecord/test/fixtures/categories_ordered.yml 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 ] 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 -- cgit v1.2.3