2011-06-16 36 views
1

在Mac OS X上運行的Rails 3.0.7與1.9.2紅寶石創建一個Rails 3名爲範圍涉及3個表

我有三個型號在他們身後表(sqlite3的用於開發,Postgres的爲正式版)。它們如下(驗證和其他不相關的線截斷):

class ServiceProvider < ActiveRecord::Base 
    has_many :services 
    has_many :advertisements, :through => :services 
    scope :active, where("service_providers.active = ?", true) 
end 

class Service < ActiveRecord::Base 
    belongs_to :service_provider 
    has_many :advertisements 
    scope :active, joins(:service_provider).where("services.active = ?", true) & ServiceProvider.active 
end 

class Advertisement < ActiveRecord::Base 
    belongs_to :service 
    scope :ranked, where("advertisements.rank > 0") 
    scope :current, where("start_date <= ? AND end_date >= ?", Date.today, Date.today) 
    scope :service_active, joins(:service) & Service.active 
    scope :active, ranked.current.service_active 
end 

正如你可以看到,每個服務提供商有很多的服務和每個服務可以有很多的廣告。廣告表中有service_id外鍵,而services表中有service_provider_id外鍵。所有漂亮的標準多對一的關係。服務提供商可以通過一個「活動」標誌變爲非活動狀態,就像個人服務以類似的方式一樣。

我想要做的就是在廣告模型上創建一個命名範圍,以給出所有排名和當前的廣告以及誰的父服務處於活動狀態的列表,以及誰的service_provider處於活動狀態。換句話說,如果服務處於非活動狀態,則指向它的所有廣告都應該變爲非活動狀態,並且如果服務提供商處於非活動狀態,則所有服務以及這些服務下的所有廣告都應變爲非活動狀態。

我在上面創建所需的命名範圍做了防刺和它的工作原理在Service.active和ServiceProvider.active水平預期,但如果我在Advertisement.active型我得到一個錯誤:

ActiveRecord::ConfigurationError: Association named 'service_provider' was not found; perhaps you misspelled it? 

我認爲這是因爲我沒有service_provider_id作爲廣告商表中的外鍵字段,但我不認爲我會這樣做,因爲它應該通過service表上的service_provider_id字段訪問service_provider。感覺就像我在廣告模型中需要一個belongs_to:service_provider,:through =>:service子句,但據我所知,這是不可能的。我嘗試了各種各樣的方法來實現這一目標,但我正在努力取得進展。

任何人都可以告訴我一個很好的優雅的方式來實現上述,理想情況下不改變我的表結構?我需要它非常高效,因爲此查詢將針對我網站上的每個頁面加載運行(每個頁面上的側邊欄廣告)。

非常感謝, 克雷格。

回答

7

我認爲有以下將工作:

class Advertisement 
    scope :service_active, joins(:service => :service_provider) 
          .where(:services => { :active => true }) 
          .where(:service_providers => { :active => true }) 
end 

那麼你應該能夠調用

Advertisement.ranked.current.service_active 

,並得到預期的結果。

+0

這很好,謝謝!這也是我尋找的精美優雅的解決方案。 Rails永遠不會令我驚歎。我今天做了很多搜索,從來沒有找到你使用過的語法。絕對是一個工具箱!謝謝你的時間! – craig1410 2011-06-16 20:49:03