使用 DataMapper 引用外键

发布于 2024-10-28 11:47:12 字数 1819 浏览 1 评论 0原文

我一直在研究这个:

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

我在 Scan 中删除了 property :in_stationproperty :out_station 并替换为:

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 不同时,我期望不同的对象。

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:

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

沉默的熊 2024-11-04 11:47:12

这样做怎么样:

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

这应该适合您,符合您的模式。

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.

一枫情书 2024-11-04 11:47:12

假设我们不想更改底层 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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文