Automatic Associations in Ruby on Rails Fixtures

Automatic associations in ruby on rails fixtures

Reading the API documentation, this is exactly how autogenerated fixtures are supposed to behave -- if you want to have a specific ID value for a fixture in advance, you should probably just assign it yourself.

If not, well, from the API docs:

The generated ID for a given label is constant, so we can discover any fixture‘s ID without loading anything, as long as we know the label.

In a Rails unit test, how can I get a User fixture to load its associated Profile?

Based on tadman's suggestion I did some more searching and found the answer elsewhere on this site, so I might as well post it.

See post titled Automatic associations in ruby on rails fixtures

Apparently the way Rails finds associated fixtures when you use labels (user: reginald) instead of IDs (user_id: 1) is by hashing the name and assuming the hash is the ID. If you set the ID to something specific, this fails. But if you let Rails automatically assign IDs it uses that hashing scheme. So the documentation for fixture association labels is missing a key tidbit--if you are using labels you must avoid applying your own IDs in the fixtures to be matched. Fixtures not being matched by labels can still have whatever ID scheme you choose.

Incorrect association in fixtures

I think it has to be with the id attribute in the repos fixture.
I'm using yml fixtures. I added the issue and the repo to the existing ones in the project.

issues.yml

issue_triage_sandbox:
user_name: bemurphy
name: issue_triage_sandbox
full_name: bemurphy/issue_triage_sandbox
language: ruby
created_at: 2012-11-10 21:50:48.351554000 Z
updated_at: 2012-11-10 21:50:48.351554000 Z
issues_count: 1

repos.yml

issue_triage_sandbox:
user_name: bemurphy
name: issue_triage_sandbox
full_name: bemurphy/issue_triage_sandbox
language: ruby
created_at: 2012-11-10 21:50:48.351554000 Z
updated_at: 2012-11-10 21:50:48.351554000 Z
issues_count: 1

From the console:

rake db:fixtures:load RAILS_ENV=test
rails c test

irb(main):001:0> i = Issue.last

=> #https://api.github.com/repos/bemurphy/issue_triage...", repo_name: nil, user_name: nil, last_touched_at: "2012-11-10 22:20:24", number: 1, created_at: "2012-11-10 23:23:45", updated_at: "2012-11-10 23:23:45", repo_id: 915227508, title: "first test issue in sinatra", html_url: "https://github.com/sinatra/sinatra/issues/1", state: "open", pr_attached: false>

irb(main):002:0> i.repo

Rails fixtures — Incrementing an ID attribute automatically?

If you don't specify an id, it will hash the label and use that as the id. Some benefits of not specifying an id:

  • Stable, autogenerated IDs
  • Label references for associations (belongs_to, has_one, has_many)
  • HABTM associations as inline lists
  • Autofilled timestamp columns
  • Fixture label interpolation
  • Support for YAML defaults

See this page in the documentation for more info on fixtures: http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

Dynamically generate fixtures in Rails via loop in YAML file

It turns out that the above YAML is valid, but that it must be loaded differently than a standard YAML file:

YAML::load(ERB.new(File.read(PATH_TO_FILE)).result)

I discovered the proper loading logic in "YAML with erb is not parsing", but wanted to add this answer since I couldn't find any examples that used a looping mechanism other than for and that interpolated to this extent.

Rails belongs_to testing

Here is what was wrong.

Automatic associations in ruby on rails fixtures

http://ar.rubyonrails.org/classes/Fixtures.html

  • See the section on "Label references for associations (belongs_to, has_one, has_many)"

Here is another optional explanation...


Essentially, you have to monkey around with your fixtures some and remove the _id from foreign keys to get associations working (oddly enough). The articles explain everything. After I RTFM everything starting working perfectly. Just needed to know where to look. Don't forget to "rake db:test:prepare" & "rake test" first!

Label references for associations

Fixtures.identify seems to be the only solution, not really beautiful but better than ids.

### in pirates.yml

reginald:
name: Reginald the Pirate
monkey_id: <%= Fixtures.identify(:george) %>

### in monkeys.yml

george:
name: George the Monkey
pirate_id: <%= Fixtures.identify(:reginald) %>

Rails fixtures -- how do you set foreign keys?

You should use named fixtures, which automatically generate an id number for you where you don't provide one. These id numbers are essentially integer hashes of whatever string you use. Don't add the "_id" if you're referencing the named version:

# recipes.yml
chicken_soup:
cookbook: my_recipes

# cookbooks.yml
my_recipes:
title: My Test Cookbook

How can I load Globalize translation fixtures to test models?

Solution

  1. Move fixtures/post_translations.yml to fixtures/post/translations.yml
  2. The key for the association in my_first_translation is globalized_model

So you will end up with this:

<!-- language: yml -->
# spec/fixtures/posts.yml

my_first_post:
author: dave

# spec/fixtures/post/translations.yml

my_first_post_translation:
locale: en
title: My first post
content: What a time to be alive!
globalized_model: my_first_post

Explanation

  1. The translation model is Post::Translation. The namespacing means that the location of the Post::Translation fixtures must follow the same nesting conventions as a model in app/models.

  2. The association name on Post::Translation (and any globalize translation model) is globalized_model. ActiveRecord::FixtureSet uses the association name to recognise the fixture key as an association.



Related Topics



Leave a reply



Submit