2011-03-09 78 views
0

一是同一對,我的模型定義:Ruby on Rails的:belongs_to的和的has_many了在同一個模型

class Certificate < ActiveRecord::Base 
    belongs_to :certificate_series 
end 

class CertificateSeries < ActiveRecord::Base 
    has_many :certificates 
    belongs_to :last_certificate_in_series, :class_name => "Certificate", :foreign_key => :last_certificate_in_series_id 
end 

我認爲協會評爲:CertificateSeries有很多證書和有證書這是最後一個系列中的一個。我想過使用have_one,但根據association basics,根據放置關聯關鍵字的位置,have_one不正確。

你可以想象得到,當你每次拿到新護照時,護照的身份都在改變(發行日期和截止日期不斷變化),但它仍然是護照。因此,您可以擁有許多實物護照(證書),但您只有1本護照(系列中的最後一本護照),並且護照屬於「護照」類別(證書系列) 。

我想要的是我可以調用CertificateSeries.last_certificate_in_series,它會返回系列中的最後一個證書。我想通過使字段last_certificate_in_series_id在數據庫級別執行此操作。我想這樣做,以減少剛剛獲得系列中最後一個數據庫的數據庫開銷。我想到的另一種方法是獲取系列中的所有證書,按日期安排它們,並獲取最新的證書。

因此,我現在有問題試圖在模型中反映這種關聯。

belongs_to :last_certificate_in_series, :class_name => "Certificate", :foreign_key => :last_certificate_in_series_id 

似乎沒有正確定義它。我可以調用CertificateSeries.last_certificate_in_series,但即使將last_certificate_in_series_id設置爲有效值時,它也只返回nilClass。

我接受其他方法的建議。

回答

0

您應該創建一個返回系列中的最後一個證書的方法。你不需要爲此創建另一個關係。

class Certificate < ActiveRecord::Base 
    belongs_to :certificate_series 
end 

class CertificateSeries < ActiveRecord::Base 
    has_many :certificates 

    def last_certificate_in_series 
    certificates.last 
    end 
end 
+0

與Peter Wong的解決方案相同,只是作爲類方法實施。正如我看到的,這將獲取屬於證書系列的所有證書,然後遍歷列表,並返回最後一個。將會有一個開銷獲取。現在,爲了簡單起見,選擇這個答案是因爲我認爲我可能在項目的早期就過度優化。 – Rystraum 2011-03-09 04:28:07

+0

我沒有辦法現在檢查,但如果我沒有弄錯,調用certificates.last應該生成查詢'SELECT * FROM certificates WHERE certificate_series_id = 1 ORDER BY id LIMIT 1'或類似的東西。當然,certificate_series_id將取決於系列的實際ID。 – 2011-03-09 04:40:33

0

其實你不需要額外的belongs_to關聯。這聽起來很自然,certificate_series.certificates的最後一個證書是你想要的。所以你可以簡單地做到這一點:

class Certificate < ActiveRecord::Base 
    belongs_to :certificate_series 
end 

class CertificateSeries < ActiveRecord::Base 
    has_many :certificates 
end 

certificate_series.certificates.last 
+0

確實,我想到了這個,但後來我想到了性能問題。 – Rystraum 2011-03-09 04:10:58

+0

因此,當您從數據庫中檢索certificate_series時,您不需要所有證書,但只需要最後一個,對吧? – PeterWong 2011-03-09 05:24:45

1

你可能會考慮acts_as_list插件。 然後在證書模式:

belongs_to :certificate_series 
acts_as_list :scope => certificate_series 
+0

順便說一下,我想過實現我自己的列表。謝謝,會檢查這個插件。 – Rystraum 2011-03-09 04:10:05

相關問題