简体   繁体   中英

Referring to many-to-many seeded data in a Rails fixture

I am developing a Rails 2.3.5 project for an inventory system. The main object is Item which has associated objects such as State and Zipcode . It also has a many-to-many association (HABTM) with Location ; so, an Item can have zero, one, or many Locations .

I use seed data in db/seeds.rb to load the State , Zipcode , and Location data, as that data is the same for all instances of this project.

I want to create a fixture for Item to help me do unit testing. This is what I have so far:

# items.yml
widget1:
  state_id:   <%= State.find_by_name('Utah').id %> 
  zipcode_id: <%= Zipcode.find_by_name('00000').id %>
  locations_id: <%= Location.find_by_name('123 Main Street').id %>

The state_id and zipcode_id work fine. My problem is the locations_id line. I do not know how to specify in the fixture file the id's for a many-to-many association.

For a many-to-many association you need an intermediate table which connects the two tables. So in this case, you'd have an items table, a locations table, and a third table items_locations which has two columns, item_id and location_id (or potentially more, depending on the specific case).

In the models, you would usually specify a has_and_belongs_to_many association for this purpose.

The items table doesn't have any column referencing the locations in this case, so you don't need to add one in the fixture. You don't need a separate fixture for the join table either though. This document explains how you define the associations in your fixture:

http://api.rubyonrails.org/v3.2.13/classes/ActiveRecord/Fixtures.html

So you would put something like this in your fixture:

locations: location1, location2, location3

...and then define these locations in the locations.yml fixture.

Sorry to dug out this old question, but I stumbled on the same problem (data already in the database by seeding) and was only able to fix it by this hack, which works but is very ugly and maybe error prone:

# items_locations.yml
some_relation:
    item_id: <%= Item.find_by_name("some name").id %>
    location_id <%= Location.find_by_name('123 Main Street').id %>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM