Rake db:fixtures:load - can't set fixture_class_name. #9516

jacobstr opened this Issue Mar 2, 2013 · 10 comments


None yet

8 participants

jacobstr commented Mar 2, 2013

I have a many to many relation using a through table:

class User < ActiveRecord::Base
  has_many :badges, :through => :users_badges 

class UsersBadges < ActiveRecord::Base
  belongs_to :user
  belongs_to :badge
  belongs_to :badgesource, :polymorphic => true

class Badge < ActiveRecord::Base
  attr_accessible :points, :description
  has_many :users, :through => :users_badges

And a fixtures file named users_badges.yaml inside of test/fixtures.

The first issue was really that it was recognizing the class name for my UsersBadges model as UsersBadge ( which I'm not sure is correct - I couldn't find documentation on this).

So - the workaround was to add set_fixture_class before the fixtures are loaded inside of test_helper.rb

Unfortunately, this only works in the test context. It's nice to interact with the fixtures in the console but running rake:db:fixtures:load does the same naming conversion translation.

When it gets the class name wrong, it doesn't correctly grok the fixture file. My fixtures are related using labels. The SQL insert statement isn't adjusted to use ids and I get:

table users_badges has no column named user:

INSERT INTO "users_badges" ("user", "badge", "badgesource") VALUES ('user1', 'mood_badge', 'rocking_out (Generic)').

The relevant code is around lib/active_record/fixtures.rb:492

schneems commented Mar 3, 2013

The convention is to use singular model names, other wise when you're dealing with multiple UsersBadges, you would call them UsersBadges-s which wouldn't make much sense. Rails expects it to be UserBadge or UsersBadge (though the first makes more sense).

If you're not following this convention, you'll need to manually specify your table name in your has_many lines. Try that and see if it fixes your issue.

You will also need to check that this behavior is the same in 4.0.0. The line you referenced is an end in master.

senny commented Mar 17, 2013

The model name should always be singular. Rails will pluralize it in many places and expects the class name to be singular.

senny commented Apr 9, 2013

I'm closing this issue as it has been over a month since we heard from you. Please feel free to report back if this issue still persists and the advice from @schneems did not fix the problem.

Thanks for reporting 💛

@senny senny closed this Apr 9, 2013
azul commented Sep 6, 2014

@senny, I've run into a similar issue. Maybe it's time to reopen this:

  • I'm using acts_as_taggable_on which has ActsAsTaggableOn::Tag and ActsAsTaggableOn::Tagging classes.
  • their fixtures live in tag.yml and tagging.yml.
  • in my tests i use set_fixture_class and everything is fine.

I run into errors when trying to load the fixtures into the database with rake db:fixtures:load though.
This is due to the fact that the rake task sends no third param to create_fixtures
while load_fixtures hands over the class lookup hash.

I was thinking about providing a patch. But I could not figure out any good place to store the class names. Including ActiveRecord::TestFixtures felt like a bit too much and it would also still require additional calls to set_fixture_class. Loading the test_helper and using the TestCase class feels wrong. So maybe these settings should go somewhere more generic and be set in an initializer or config?

senny commented Sep 8, 2014

@jacobstr thanks for reporting back. I'll reopen.

@senny senny reopened this Sep 8, 2014

This issue has been automatically marked as stale because it has not been commented on for at least
three months.

The resources of the Rails team are limited, and so we are asking for your help.

If you can still reproduce this error on the 4-1-stable, 4-0-stable branches or on master,
please reply with all of the information you have about it in order to keep the issue open.

Thank you for all your contributions.

@rails-bot rails-bot added the stale label Jan 2, 2015
@rafaelfranca rafaelfranca added pinned and removed stale labels Mar 20, 2015
repinel commented Jun 12, 2015

Why trying to duplicate the issue using master, I didn't have any SQL problem. However, the fixture were not properly loaded into the database.

My sample app has the following models:

class Post < ActiveRecord::Base
  self.table_name = 'records'
  has_many :comments

class Comment < ActiveRecord::Base
  belongs_to :post

And schema.rb:

  create_table "comments", force: :cascade do |t|
    t.string   "content"
    t.integer  "post_id"

  create_table "records", force: :cascade do |t|
    t.string "title"


  title: foo


  content: 'great'
  post: one

You may check by the app tests that the fixtures load fine for the tests having set_fixture_class records: Post in the test_helper.rb.

@senny What's your opinion on having something like a mapping.rb file on fixtures directory that would holder the set_fixture_class statements make it easier to share that with the db:fixtures:load? One other option could be having the class name defined in the fixture itself with something like CLASS_NAME and being ignored just like is done for DEFAULTS.

senny commented Jun 15, 2015

Backtracking in the git history, it looks like ada11d6 was the origin of set_fixture_class. I still feel like this configuration is directly related to the fixture and not the TestCase (the way it's currently implemented).

If that's the case (maybe @jeremy can elaborate more about the origin) I think we could make the configuration accessible directly in the fixture file itself. Something along the lines of:

<% set_fixture_class "Book" %>

  title: "Odyssey"

  title: "Ulysses"
trak3r commented Aug 21, 2015

I'm getting bit by this now as well.

I agree with @senny sentiment, "feel like this configuration is directly related to the fixture and not the TestCase" and also his suggestion for the declaration in the fixture file.

@senny senny closed this in #20574 Sep 30, 2015
senny commented Sep 30, 2015

with #20574 merged Rails 5 will allow you to configure the fixture class directly in the YAML file:


  model_class: User
  name: David
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment