2010-08-08 85 views
2

我有模型clubcourse其中一個課程屬於一個俱樂部和一個俱樂部有很多課程。導軌:有條件加載協會

當我加載一個俱樂部,我也想加載它的相關課程,但我只想加載符合條件測試(approved? == true)的那些。

這是簡單的如何做到這一點,如果我直接與課程工作:

@courses = Course.find(:all, :conditions => {:approved => true }) 

但我想這樣做,因爲語句的一部分:

@club = Club.find(params[:id]) 

,因爲我的看法是以這種方式構建的,我寧願不必改變它們全部。

謝謝!

回答

0

最終的解決方案來自於答案的組合,但都沒有完全解決。

目前的解決方案: 我利用在course模型一對夫婦命名範圍的實現,同時保持自己的觀點儘可能具有普遍性我想要的功能(能夠乾涸代碼是必須的)。

所以course模型看起來有點像這樣:

class Course < ActiveRecord::Base 
    belongs_to :club 

    named_scope :have_approval, :conditions => { :approved => true } 
    named_scope :need_approval, :conditions => { :approved => false } 
end 

,並收集所有經批准的課程,因爲它是那麼簡單:用club工作時

@approved_courses = Course.have_approval 

或者獲得批准在俱樂部的課程是一樣容易:

@club = Club.find(:first) 
@approved_courses_in_club = @club.courses.have_approval 

命名範圍是男人!

+1

您可以使用動態範圍而不是named_scope,即'@ club.courses.scoped_by_approval(true)'或'@ club.courses.scoped_by_approval(false)'。 – 2010-08-09 18:36:15

+0

嘿,現在只是漂亮! – Jay 2010-08-10 01:29:12

2

如果你只有當它已被批准考慮俱樂部的過程中,你可以做

class Club < ActiveRecord::Base 
    has_many :courses, :conditions => {:approved => true} 
end 

,並在控制器

@club = Club.find(params[:id], :include => :courses) 

現在,我不知道如果我誤解你了,但你說過「你的觀點是這樣構建的」。你的意思是你的控制器?因爲如果你在你的觀點中有這樣的邏輯... DHH每次有人這樣做會殺死一隻小貓。

+0

可憐的小貓,但沒有。我擔心不得不同時加載'@ club'和'@ courses'變量......這意味着要刪除我的視圖中的所有'@ club.courses'引用。 我有一個管理員命名空間,我想加載未經認可的課程(就像條件不在模型中一樣),我將如何使用您的解決方案來做到這一點? – Jay 2010-08-08 06:21:35

1

您可以使用default_scope此:

class Club < ActiveRecord::Base 
    has_many :courses, conditions => {:approved => true} 
    default_scope :include => :courses 
end 

class Course < ActiveRecord::Base 
    default_scope :conditions => {:approved => true} 
end 

現在你可以這樣做:

@club = Club.find(1) # this will eager load approved courses. 

參考:

Articledefault_scope

注1

我改變了courses ASSOCATION在Club類選擇認可的課程。理論上,這不是必需的,因爲Course類具有默認範圍。但是,它看起來像默認範圍不適用於預先加載的查詢。

注2

我個人並不急於負載Course對象通過default_scope。通過default_scope做到這一點,可以根據您的需要爲您提供一個不顯眼的解決方案。

我會將include子句添加到find調用中,只有在需要時纔會加載Course對象。

注3

@Ryan比格:

約默認範圍瑞恩·貝茨會談通過這個他screen cast一半。他給出了一個使用默認示波器排除刪除記錄的例子,即

default_scope :conditions => "delete_at IS NULL" 

我認爲這個用例是類似的。當我發現問題時,課程模型的主要操作在批准的記錄上,default_scopeconditions選項確保。要覆蓋default_scope,用戶可以使用with_exclusive_scope方法。

Club.with_exclusive_scope{find(1)} 
+0

我不會在'default_scope'中使用:conditions ** ever **:Rails如何區分'default_scope'條件和您指定的另一組條件?相反,我會使用'named_scope'來調用它。 @丘巴斯的解決方案也很好。 – 2010-08-08 05:58:53

+0

我不同意,過濾'deleted'和'approved'記錄是default_scope的合適用法。在這種情況下,'Course'模型的每個'find'操作都需要過濾未經認可的課程。在用戶需要包含未經批准的記錄的情況下,他可以使用'with_exclusive_scope'。 – 2010-08-08 07:21:49

+0

用戶說:「因爲我的視圖是以這種方式構建的,我寧願不必更改所有這些視圖。」此解決方案使用戶可以毫不諱言地實現功能。 – 2010-08-08 07:29:03