Referencing foreign keys with DataMapper
I've been looking through this:
http://datamapper.org/docs/find
But haven't been able to gleam what I'm looking for, though I know it's quite simple.
I have two tables, scans and stations, with the relevant fields:
STATIONS - id (primary key), name
SCANS - id (primary key), item_id, in_station, out_station
Where in_station
and out_station
are foreign keys to the id
field in the stations
table.
I have a Scan
object
class Scan
include DataMapper::Resource
property :id, Integer, :key => true
property :item_id, Integer
property :in_station, Integer
property :out_station, Integer
end
So right now, I can do Scan.all(:item_id => @barcode)
to get all the scans on a particular item, and I've got the in_station
id and out_station
id. What's the best way of getting the names, though, instead of ids. I assume it's gotta be easier than for every scan calling Station.get(:id=> scan.in_station)
.
This is easy enough using SQL, but how can I alter Scan/Station to either get the name or have a property that's a Station object, so I can do something like scan.station.name?
EDIT:
I've almost got this working. I have a Station class:
开发者_C百科class Station
include DataMapper::Resource
property :id, Integer, :key => true
property :name, String
end
and I got rid of property :in_station
and property :out_station
in Scan
and replaced with:
belongs_to :in_station, :model => 'Station', :child_key => 'id'
belongs_to :out_station, :model => 'Station', :child_key => 'id'
Which I think/hope is saying "there's a field called in_station which is a foreign key into the Station table and one called out_station which is the same". Indeed, in_station and out_station are now instances of Station, BUT, they're the object. Even though in_station and out_station are different values, I'm getting the same object for each on every Scan. What am I doing wrong, how can I indicate that in_station and out_station are both references to Station but, when their ids are different, I expect different objects.
How about doing this:
class Station
include DataMapper::Resource
property :id, Serial
# rest of the properties
has n, :scans
end
class Scan
include DataMapper::Resource
property :id, Serial
# rest of the properties
belongs_to :station
end
Then you just do this to access the associated station:
station = Station.create
scan = station.scans.create
scan.station # returns the associated station
That should work for you at match your schema.
The assumption is that we don't want to change the underlying SQL schema. So we have to tell DataMapper to use the existing foreign key names (in_station and out_station). The twist is that DataMapper will choke if the association name is the same as the child key. That's why I have the 'my_' prefix on the association names.
class Scan
include DataMapper::Resource
#rest of the properties
belongs_to :my_in_station, :model => 'Station', :child_key => 'in_station'
belongs_to :my_out_station, :model => 'Station', :child_key => 'out_station'
end
Usage
s = Scan.get(id)
s.my_in_station.name
s.my_out_station.name
精彩评论