6

我有两张桌子:

货币和汇率

currencies: id:int, code:string, name: string

rates: id:int, top_currency_id:int, bottom_currency_id:int, rate:float

我有两个活跃的记录:

class Rate < ActiveRecord::Base
  attr_accessible :bottom_currency, :rate, :top_currency, :top_currency_id

  belongs_to :top_currency, :class_name => 'Currency', :foreign_key => 'top_currency_id'
  belongs_to :bottom_currency, :class_name => 'Currency', :foreign_key => 'bottom_currency_id'
end


class Currency < ActiveRecord::Base
  attr_accessible :code, :name

  has_many :rates
end

所以问题是:当我试图执行以下代码时: top_currency = Currency.find_by_id(1) @test = Rate.where(:top_currency=>top_currency)

我收到以下错误:

Mysql2::Error: Unknown column 'rates.top_currency' in 
'where clause': SELECT `rates`.* FROM `rates`  WHERE `rates`.`top_currency` = 1

为什么 Rails 的魔法不起作用?

非常感谢。

4

3 回答 3

6

在您的两种belongs_to方法中,将foreign_key选项更改为primary_key,其他所有内容保持不变。

belongs_to :top_currency, :class_name => 'Currency', :primary_key => 'top_currency_id'
# ...

默认情况下,关联对象的主键是id. 但是,您的货币模型具有三个主键,预期id加上两个额外的键:top_currency_idbottom_currency_id. Active Record 需要知道要查找的密钥。primary_key用选项 告诉它。

foreign_key当外键不同于关联名称 ( belongs_to :name) 加“ ”时,需要该选项_id。由于您的外键与关联名称加“ _id,”相匹配,因此您不需要使用该foreign_key选项。

于 2013-02-24T20:53:13.143 回答
5

据我所知,您的代码理论上应该可以工作。但我确实认为你有点多余。

这样做就足够了:

class Rate < ActiveRecord::Base
  belongs_to :top_currency, class_name: 'Currency'
  belongs_to :bottom_currency, class_name: 'Currency'
end

Rails 会推断出top_currencyistop_currency_idbottom_currency_idfor的外键bottom_currency

于 2013-02-24T20:45:09.450 回答
0

我不认为你可以这样查询关系。要使用您的示例:

top_currency = Currency.find_by_id(1)
@test = Rate.where(:top_currency=>top_currency)

您必须将其更改为:

top_currency = Currency.find_by_id(1)
@test = Rate.where(:top_currency_id => top_currency.id)

但这样做可能更容易:

top_currency = Currency.find_by_id(1)
@test = top_currency.rates
于 2013-02-25T02:02:22.730 回答