2013-02-24 35 views
4

我有兩個表:多belongs_to的同一個表

貨幣和利率

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的魔術不起作用?

非常感謝。

+0

該錯誤提示' top_currency'不是'rates'表中的列,您確定將您的更改遷移到您正在使用的環境中嗎? – JaredMcAteer 2013-02-24 20:14:35

+0

@JaredMcAteer我有top_currency_id列,我認爲Rails應該查找top_currency的top_currency_id列。 – Grisha 2013-02-24 20:17:24

回答

4

在您的兩個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。活動記錄需要知道要查找哪個密鑰。用primary_key選項告訴它。

當外鍵不同於關聯名稱(belongs_to :name)加「_id」時,需要foreign_key選項。由於您的外鍵匹配關聯名稱加上「_id」,因此不需要使用foreign_key選項。

+0

不,不幸的是我只有一個主鍵。 – Grisha 2013-02-25 05:39:32

3

從我看到的,你的代碼應該在理論上工作。但我確實認爲你有點多餘。

它應該是不夠的,只是這樣做:

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

Rails會推斷爲top_currency外鍵是top_currency_id,並bottom_currency_idbottom_currency

+0

您確定類名不應該是符號或字符串嗎? – 2015-12-03 18:00:21

+0

@QPaysTaxes謝謝你指出,糾正。 – Jesper 2015-12-04 07:14:09

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 
+0

是的,'@test = Rate.where(:top_currency_id => top_currency.id)'偶'@test = Rate.where(:top_currency_id => top_currency)'效果很好。但是我想讓'Rate.where(:top_currency => top_currency)'工作 – Grisha 2013-02-25 05:36:57

+0

只是好奇你爲什麼如此致力於讓Rate.where(:top_currency => top_currency)'當你設置的關聯給你'top_currency.rates'方法做同樣的事情? – 2013-02-25 14:16:41

+0

@MollyStruve其實我需要執行以下請求:'Rate.where(:top_currency => top_currency,:bottom_currency => bottom_curency)' – Grisha 2013-02-25 14:45:34