diff options
author | Tongfei Gao <gaotongfei1995@gmail.com> | 2019-05-18 20:58:22 +0800 |
---|---|---|
committer | Tongfei Gao <gaotongfei1995@gmail.com> | 2019-07-27 16:40:16 +0800 |
commit | c09a4fd23d7d52552132edde7ad155f366c560b8 (patch) | |
tree | 689a66272dffccef08230af259a687ed4be960cd /activerecord | |
parent | d1ffe59ab5fd6e811833c127d43b32e87b5d7131 (diff) | |
download | rails-c09a4fd23d7d52552132edde7ad155f366c560b8.tar.gz rails-c09a4fd23d7d52552132edde7ad155f366c560b8.tar.bz2 rails-c09a4fd23d7d52552132edde7ad155f366c560b8.zip |
Allow specify fixtures to be ignored
Allow specifying what fixtures can be ignored by setting
`ignore` in fixtures YAML file:
# users.yml
_fixture:
ignore:
- base
base: &base
admin: false
introduction: "This is a default description"
admin:
<<: *base
admin: true
visitor:
<<: *base
In the above example, "base" fixture will be ignored when creating
users fixture. This is helpful when you want to inherit attributes
and it makes your fixtures more "DRY".
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/CHANGELOG.md | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/fixture_set/file.rb | 6 | ||||
-rw-r--r-- | activerecord/lib/active_record/fixtures.rb | 45 | ||||
-rw-r--r-- | activerecord/test/cases/fixtures_test.rb | 27 | ||||
-rw-r--r-- | activerecord/test/fixtures/other_books.yml | 26 | ||||
-rw-r--r-- | activerecord/test/fixtures/parrots.yml | 8 |
6 files changed, 111 insertions, 5 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 366032c734..7f2071189b 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,7 @@ +* Allow specifying fixtures to be ignored by setting `ignore` in YAML file's '_fixture' section. + + *Tongfei Gao* + * Make the DATABASE_URL env variable only affect the primary connection. Add new env variables for multiple databases. *John Crepezzi*, *Eileen Uchitelle* diff --git a/activerecord/lib/active_record/fixture_set/file.rb b/activerecord/lib/active_record/fixture_set/file.rb index f1ea0e022f..b2030a5bb9 100644 --- a/activerecord/lib/active_record/fixture_set/file.rb +++ b/activerecord/lib/active_record/fixture_set/file.rb @@ -29,6 +29,10 @@ module ActiveRecord config_row["model_class"] end + def ignored_fixtures + config_row["ignore"] + end + private def rows @rows ||= raw_rows.reject { |fixture_name, _| fixture_name == "_fixture" } @@ -40,7 +44,7 @@ module ActiveRecord if row row.last else - { 'model_class': nil } + { 'model_class': nil, 'ignore': nil } end end end diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb index 046ed0e95c..3df4b3c87f 100644 --- a/activerecord/lib/active_record/fixtures.rb +++ b/activerecord/lib/active_record/fixtures.rb @@ -420,6 +420,29 @@ module ActiveRecord # # Any fixture labeled "DEFAULTS" is safely ignored. # + # Besides using "DEFAULTS", you can also specify what fixtures will + # be ignored by setting "ignore" in "_fixture" section. + # + # # users.yml + # _fixture: + # ignore: + # - base + # # or use "ignore: base" when there is only one fixture needs to be ignored. + # + # base: &base + # admin: false + # introduction: "This is a default description" + # + # admin: + # <<: *base + # admin: true + # + # visitor: + # <<: *base + # + # In the above example, 'base' will be ignored when creating fixtures. + # This can be used for common attributes inheriting. + # # == Configure the fixture model class # # It's possible to set the fixture's model class directly in the YAML file. @@ -614,7 +637,7 @@ module ActiveRecord end end - attr_reader :table_name, :name, :fixtures, :model_class, :config + attr_reader :table_name, :name, :fixtures, :model_class, :ignored_fixtures, :config def initialize(_, name, class_name, path, config = ActiveRecord::Base) @name = name @@ -647,8 +670,8 @@ module ActiveRecord # Returns a hash of rows to be inserted. The key is the table, the value is # a list of rows to insert to that table. def table_rows - # allow a standard key to be used for doing defaults in YAML - fixtures.delete("DEFAULTS") + # allow specifying fixtures to be ignored by setting `ignore` in `_fixture` section + fixtures.except!(*ignored_fixtures) TableRows.new( table_name, @@ -667,6 +690,21 @@ module ActiveRecord end end + def ignored_fixtures=(base) + @ignored_fixtures = + case base + when Array + base + when String + [base] + else + [] + end + + @ignored_fixtures << "DEFAULTS" unless @ignored_fixtures.include?("DEFAULTS") + @ignored_fixtures.compact + end + # Loads the fixtures from the YAML file at +path+. # If the file sets the +model_class+ and current instance value is not set, # it uses the file value. @@ -678,6 +716,7 @@ module ActiveRecord yaml_files.each_with_object({}) do |file, fixtures| FixtureSet::File.open(file) do |fh| self.model_class ||= fh.model_class if fh.model_class + self.ignored_fixtures ||= fh.ignored_fixtures fh.each do |fixture_name, row| fixtures[fixture_name] = ActiveRecord::Fixture.new(row, model_class) end diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb index a7f01e898e..7ad032a632 100644 --- a/activerecord/test/cases/fixtures_test.rb +++ b/activerecord/test/cases/fixtures_test.rb @@ -1279,6 +1279,33 @@ class CustomNameForFixtureOrModelTest < ActiveRecord::TestCase end end +class IgnoreFixturesTest < ActiveRecord::TestCase + fixtures :other_books, :parrots + + test "ignores books fixtures" do + assert_raise(StandardError) { other_books(:published) } + assert_raise(StandardError) { other_books(:published_paperback) } + assert_raise(StandardError) { other_books(:published_ebook) } + + assert_equal 2, Book.count + assert_equal "Agile Web Development with Rails", other_books(:awdr).name + assert_equal "published", other_books(:awdr).status + assert_equal "paperback", other_books(:awdr).format + assert_equal "english", other_books(:awdr).language + + assert_equal "Ruby for Rails", other_books(:rfr).name + assert_equal "ebook", other_books(:rfr).format + assert_equal "published", other_books(:rfr).status + end + + test "ignores parrots fixtures" do + assert_raise(StandardError) { parrots(:DEFAULT) } + assert_raise(StandardError) { parrots(:DEAD_PARROT) } + + assert_equal "DeadParrot", parrots(:polly).parrot_sti_class + end +end + class FixturesWithDefaultScopeTest < ActiveRecord::TestCase fixtures :bulbs diff --git a/activerecord/test/fixtures/other_books.yml b/activerecord/test/fixtures/other_books.yml new file mode 100644 index 0000000000..62806c03d7 --- /dev/null +++ b/activerecord/test/fixtures/other_books.yml @@ -0,0 +1,26 @@ +_fixture: + model_class: Book + ignore: + - PUBLISHED + - PUBLISHED_PAPERBACK + - PUBLISHED_EBOOK + +PUBLISHED: &PUBLISHED + status: :published + +PUBLISHED_PAPERBACK: &PUBLISHED_PAPERBACK + <<: *PUBLISHED + format: "paperback" + language: :english + +PUBLISHED_EBOOK: &PUBLISHED_EBOOK + <<: *PUBLISHED + format: "ebook" + +awdr: + <<: *PUBLISHED_PAPERBACK + name: "Agile Web Development with Rails" + +rfr: + <<: *PUBLISHED_EBOOK + name: "Ruby for Rails" diff --git a/activerecord/test/fixtures/parrots.yml b/activerecord/test/fixtures/parrots.yml index 8425ef98e0..4f0a090e03 100644 --- a/activerecord/test/fixtures/parrots.yml +++ b/activerecord/test/fixtures/parrots.yml @@ -1,3 +1,9 @@ +_fixture: + ignore: DEAD_PARROT + +DEAD_PARROT: &DEAD_PARROT + parrot_sti_class: DeadParrot + george: name: "Curious George" treasures: diamond, sapphire @@ -17,7 +23,7 @@ polly: name: $LABEL killer: blackbeard treasures: sapphire, ruby - parrot_sti_class: DeadParrot + <<: *DEAD_PARROT DEFAULTS: &DEFAULTS treasures: sapphire, ruby |