2015-09-13 25 views
0

我想爲一個類創建一個class method,繼承ActiveRecord:Base。 該方法需要做的是添加基於選項的where子句,它運作良好。爲ActiveRecord_Relation調用ActiveRecord類方法作爲接收者

class Article < ActiveRecord::Base 

    def self.list_by_params(params={}) 
    articles = self 
    articles = articles.where(author_id: params[:author_id]) unless params[:author_id].blank? 
    articles = articles.where(category_id: params[:category_id]) unless params[:category_id].blank? 
    articles = articles.where("created_at > ?", params[:created_at].to_date) unless params[:created_at].blank? 
    articles 
    end 

end 

這段代碼在調用等情況下正常工作:

articles = Article.list_by_params({author_id: 700}) 
#=> Works fine as I expected. 

articles = Article.joins(:authors).list_by_params({author_id: 700}) 
#=> Works fine as I expected. 

然而,問題是,如果我要撥打的list_by_params沒有過濾參數,可以再它失去了往日的關係。例如:

articles = Article.joins(:authors).list_by_params({}) 
#=> articles is just a `Article` (not an ActiveRecord_Relation) class itself without joining :authors. 

有沒有可能我犯了一個錯誤?

在此先感謝。

+0

定義實例方法(不是一類一)'list_by_params',我看不出有任何理由爲什麼這個'Article.list_by_params'不是扔NoMethod錯誤。 –

+0

您是否找到解決方案?如果我的回答不起作用。它有什麼問題? – Albin

回答

1

你在找什麼是scope

我會做這樣的事情

scope :for_author, lambda { |author| where(author_id: author) unless author.blank? } 
scope :in_category, lambda { |category| where(category_id: category) unless category.blank? } 
scope :created_after, lambda { |date| where('created_at > ?', date.to_date) unless date.blank? } 

scope :list_by_params, lambda do |params| 
    for_author(params[:author_id]) 
    .in_category(params[:category_id]) 
    .created_after(params[:created_at]) 
end 

現在你可以重用你查詢的組成部分。所有東西都有一個名稱,讀取代碼變得更容易。

0

對於自我解釋,我已經通過使用where(nil)解決了這些問題。

實際上,Model.scoped返回匿名作用域,但該方法自Rails版本4以來已被棄用。現在,where(nil)可以替代功能。

class Article < ActiveRecord::Base 

    def self.list_by_params(params={}) 
    articles = where(nil) # <-- HERE IS THE PART THAT I CHANGED. 
    articles = articles.where(author_id: params[:author_id]) unless params[:author_id].blank? 
    articles = articles.where(category_id: params[:category_id]) unless params[:category_id].blank? 
    articles = articles.where("created_at > ?", params[:created_at].to_date) unless params[:created_at].blank? 
    articles 
    end 

end 
相關問題