2013-01-16 27 views
2

我有一個Camping,它有一個Author。一個Author有很多Campings從相關對象中獲取頂級x項目

入門的「前5名」,定義爲「最後5個野營」與做:

@author.campings.order(:created_at).limit(5) 

,但我想這個概念,如果「前5名」被移動到了野營模型,對我來說似乎更清潔;畢竟,Camping是唯一知道top是什麼的人。

喜歡的東西

@author.campings.top 

但如何定義這個上Camping@author.campings不是Camping,而是ActiveRecord::Relation。因此,像在模型以下/ camping.rb不起作用:

# Scope for "top" campings 
def top(amount) 
    self.order("created_at").limit(amount) 
end 

用作

@author.top(5) 

現在,我只需要這個「頂」事情的經過的關係,@author以上提到的例子。目前,「頂部」的定義僅僅是「最後5個露營」,但在下一次迭代中,根據視圖,評分或其他參數以及Camping上的字段的數量,這將更加複雜。這導致我相信Camping是定義「top」的正確位置,而不是Author

我可以將其添加到Author,但我的知識水平有限,感覺像是違反了隔離模式;作者突然需要知道的關於野營的領域:

# Last 5 campings for this author 
def top_campings(amount) 
    campings.order("created_at").limit(amount) 
end 

用作

@author.top_campings(5) 

如何這種關係通常解決了嗎?

+0

我認爲你最後一個例子是罰款。它沒有違反任何規定,只是做它應該做的事情。 – MurifoX

+0

我給這個例子命名錯了。對困惑感到抱歉。最新的編輯修復了這一點。我想更清楚地指出,@ author.top_campings將有關「露營」的知識拉入「作者」。我現在澄清說。 – berkes

回答

1

你將要定義你的野營類top這樣:

class Camping < ActiveRecord::Base 
    def self.top(count) 
    order(:created_at).limit(count) 
    end 
end 

當你將它定義爲一個類的方法,它可以通過ActiveRecord::Relation,這樣你就可以調用@author.campings.top(5)

+0

我錯過了「自我」課堂的方法。將這個自我從回報中移動到方法定義中解決了我的問題。謝謝。 – berkes

2

在Rails 3,您可以使用scopes with arguments

class Camping < ActiveRecord::Base 
    scope :top, lambda { |amount| order("created_at").limit(amount) } 
end 

(這是一樣的添加類方法Camping,我想這兩個方面都OK,所以你可以選擇你喜歡的一個)

您可以使用範圍如下:

@author.campings.top(5) 
+0

我更喜歡使用lambdas作爲範圍的類方法,但這也是一種有效的方法 –

+0

再次閱讀官方Rails指南,我發現我的問題已經在那裏得到了答覆:$。他們用一個lambda解釋了這個範圍,然後解釋了爲什麼這不是一個好主意,並且類方法是一種方法。儘管有兩種選擇都很好;謝謝。 – berkes