Rails 3: Multiple has_one associations & seeding
I'm working with a data concept that Rails doesn't seem to do great with - a Route has two (and only two) Airports. I finally figured out how to hard-code my foreign keys so that they would be sensible.
My models/route.rb
is pretty simple:
class Route < ActiveRecord::Base
has_one :airport, :foreign_key => 'from_airport_id', :class_name => 'Airport'
has_one :airport, :foreign_key => 'to_airport_id', :class_name => 'Airport'
end
This all seems to be working fine but I can't seem to get it to seed correctly.
My seeds.rb
looks like so:
Airport.delete_all
@kpdx = Airport.create(:icao => 'KPDX', :name => 'Portland International Airport', :lat => '45.58869934', :lon => '-122.5979996')
@ksea = Airport.create(:icao => 'KSEA', :name => 'Seattle Tacoma International Airport', :lat => '47.4490013122559', :lon => '-122.30899810791')
Route.delete_all
Route.create(:from_airport_id => @kpdx, :to_airport_id => @ksea, :route => "RIVR6 BTG OLM6")
Route.create(:from_airport_id => @kpdx, :to_airport_id => @ksea, :route => "BTG OLM OLM6")
Route.create(:from_airport_id => Airport.find_by_icao("KSEA"), :to_airport_id => Airport.find_by_icao("KPDX"), :route => "SEATL4 SEA HELNS4")
Route.create(:from_airport_id => Airport.find_by_icao("KSEA"), :to_airport_id => Airport.find_by_icao("KPDX"), :route => "SEA HELNS4")
Note that I have two different ways of trying to tell the seed data to go from one of the airports I created to the other. Neither one works. When I run rake db:seed
, all of the from_airport_id
and to_airport_id
fields are just set to 1, when the开发者_如何学C IDs in the airport
table are incrementing (23 & 24 in my current run).
So I have two questions:
- Is there a better way to handle the model code than what I'm doing?
- What am I doing wrong in seeding :-)
Thanks!
I would change your model to specify a different symbol for each relationship:
class Route < ActiveRecord::Base
has_one :from_airport, :foreign_key => 'from_airport_id', :class_name => 'Airport'
has_one :to_airport, :foreign_key => 'to_airport_id', :class_name => 'Airport'
end
Since enabling a has_one
lets you access that relationship through the name (e.g. route.airport
), these need to be different.
To get your seeding to work, call .id
on the airport:
Route.create(:from_airport_id => @kpdx.id, :to_airport_id => @ksea.id, :route => "RIVR6 BTG OLM6")
Example:
ruby-1.9.2-p136 :001 > a = Airport.create(:icao => 'KPDX', :name => 'Portland International Airport')
=> #<Airport id: 1, icao: "KPDX", name: "Portland International Airport", created_at: "2011-03-01 02:44:42", updated_at: "2011-03-01 02:44:42">
ruby-1.9.2-p136 :002 > b = Airport.create(:icao => 'ABCD', :name => 'Another Airport')
=> #<Airport id: 2, icao: "ABCD", name: "Another Airport", created_at: "2011-03-01 02:46:22", updated_at: "2011-03-01 02:46:22">
ruby-1.9.2-p136 :003 > r = Route.create(:to_airport_id => a.id, :from_airport_id => b.id)
=> #<Route id: 3, from_airport_id: 2, to_airport_id: 1, route: nil, created_at: "2011-03-01 02:46:36", updated_at: "2011-03-01 02:46:36">
精彩评论