I was faced with the same problem. I came up with following approach after I did some trial-and-error, read through documentation about fixtures, associations and @barnaclebarnes answer to this question.
I did this with rails 4.2.0 and acts-as-taggable-on 3.5.0.
Remark:
My previous answer did the trick, but was a bit wacky. I completly rewrote it after @David pointed me to a cleaner way - completly ommited my Trial and Error and stuck to the solution.
An approach facilitating more of the on-board facilities of rails
@barnaclebarnes solution would provide a little more automatism, but also means much more typing and bookkeeping on ids. So I kept looking for a more concise way.
Polymorphic relations
acts_as_taggable_on uses a polymorphic relation named taggable to implement the relation between tags and different models. See the rails guide on associations for details on polymorphic relations.
Advanced Fixtures
The rubydoc of ActiveRecord::FixtureSet describes the workings of ActiveRecord and what it does with relations of fixtures (chapter Label references for associations):
Active Record reflects on the fixture's model class, finds all the belongs_to associations, and allows you to specify a target label for the association [...] rather than a target id for the FK [...].
A bit further down on the page, there are also some details on polymorphic belongs_to.
This would allow for a tagging fixture definition like this:
tagging:
taggable: foo (Klass)
context: tags
tag: bar
Namespaced Fixtures and Models
ActiveRecord::TestFixtures provides a method to explicitly set the model class for a fixture in case it can not be inferred.
In other words: you can use directories to namespace fixtures and match them with their namespaced models.
To load test data for tags and taggings of acts_as_taggable_on we can put their fixtures in the subfolder fixtures/acts_as_taggable_on/
(Remark: fixtures/ActsAsTaggableOn/
would also work)
Put It All Together
# models/item.rb
class Item < ActiveRecord::Base
acts_as_taggable_on
end
# fixtures/items.yml
item_1: {}
item_2: {}
# fixtures/acts_as_taggable_on/tags.yml
tag_1:
name: tag_1
tag_2:
name: tag_2
# fixtures/acts_as_taggable_on/taggings.yml
tagging_1
taggable: item_1 (Item)
context: tags
tag: tag_1
If you erb up the yaml files this allows for a pretty low maintanance definition of taggable models and their instances.
ActsAsTaggableOn
withset_fixture_class
. Eg. in yourtest_helper.rb
, right afterfixtures :all
, addset_fixture_class "tags" => ActsAsTaggableOn::Tag
andset_fixture_class "taggings" => ActsAsTaggableOn::Tagging
. And voila! No need to have new models namedTag
andTagging
. hth – Dextrorotation