使用DataMapper引用外键

时间:2011-03-31 16:46:45

标签: ruby-on-rails ruby datamapper

我一直在看这个:

http://datamapper.org/docs/find

但是我一直无法看到我正在寻找的东西,虽然我知道这很简单。

我有两个表格,扫描和电台,以及相关字段:

STATIONS - id (primary key), name
SCANS    - id (primary key), item_id, in_station, out_station

其中in_stationout_stationid表中stations字段的外键。

我有一个Scan对象

class Scan
    include DataMapper::Resource

    property :id,                       Integer, :key => true
    property :item_id,                  Integer
    property :in_station,               Integer
    property :out_station,              Integer
end

现在,我可以Scan.all(:item_id => @barcode)对特定项目进行所有扫描,并且我已获得in_station ID和out_station ID。但是,获取名称的最佳方式是什么,而不是ID。我认为它比每次调用Station.get(:id=> scan.in_station)更容易。

这很容易使用SQL,但是如何更改Scan / Station以获取名称或具有属于Station对象的属性,因此我可以执行类似scan.station.name的操作?

修改

我几乎得到了这个工作。我有一个Station类:

class Station
    include DataMapper::Resource

    property :id, Integer, :key => true
    property :name, String
end

我在property :in_station中删除了property :out_stationScan,并替换为:

belongs_to :in_station,        :model => 'Station', :child_key => 'id'
belongs_to :out_station,       :model => 'Station', :child_key => 'id'

我认为/希望说“有一个名为in_station的字段,它是一个外键进入Station表,一个名为out_station,它是相同的”。实际上,in_station和out_station现在是Station的实例,但是它们是对象。即使in_station和out_station是不同的值,我在每次扫描时都会获得相同的对象。我做错了什么,我怎么能指出in_station和out_station都是对Station的引用,但是当它们的id不同时,我期待不同的对象。

2 个答案:

答案 0 :(得分:2)

这样做:

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

然后你这样做才能访问相关的电台:

station = Station.create
scan    = station.scans.create

scan.station # returns the associated station

这应该适合您的架构。

答案 1 :(得分:1)

假设我们不想更改底层SQL架构。因此,我们必须告诉DataMapper使用现有的外键名称(in_station和out_station)。扭曲的是,如果关联名称与子键相同,DataMapper将会阻塞。这就是我在关联名称上加上'my_'前缀的原因。

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

用法

s = Scan.get(id)
s.my_in_station.name
s.my_out_station.name