2012-03-27 12 views

答えて

0

あなたは

scope :archived, where(:day_id => Day.where("year_id != #{DateTime.now.year}").collect{ |d| d.id } 

を、次のような何かを行うことができますしかし、これは2つのクエリを生成し、unncessaryあなたのレールコードから参加します。理想的には、SQLを介してこの結合を行い、1つのクエリでのみチェックを行う必要があります。

だから、結果として得られるモデルは

class Model 

    belongs_to :day 

    scope :archieved, joins(:day).where("days.year_id != #{DateTime.now.year}") 

end 

は、より多くの情報

http://guides.rubyonrails.org/active_record_querying.html#specifying-conditions-on-the-joined-tables

+0

完璧な、これは私が探していたものです、ありがとう! –

+1

あなたは隠れたバグを見落としました。 ModelクラスがDec31の23:00にロードされ、スコープがJan1の02:00に使用されるとどうなりますか? –

0

このようなことはできますか?

your_logic = "year_id != #{DateTime.now.year}".collect{ |d| d.id }.join(",")} 
scope :archived, :conditions => Day.where(your_logic)["day_id"] 

私はちょうどday_idを引き出す最初のオブジェクトにアクセスすることによりday_id INを置き換えます。簡単な再書き込みについては

3

元の範囲とamitambの溶液中の隠されたバグがありますについては、以下を参照してください、次のようなものである必要があります。あなたはこれを言う理由scopeので、クラスメソッドである:クラスが解析され、ロードされている間

scope :blahblah, arguments 

arguments式が評価されます。特に、DateTime.now.yearは、クラスがRails環境にロードされるときに評価されます。

where('days.year_id != 2012') 

、あなたは2013年1月1日に数時間後にスコープを使用している場合、それはまだ2012を使用することになります。クラスは、2012年12月31日にロードされている場合は結果的に、そしてwhereになります年として

scope :archived, -> { joins(:day).where('days.year_id != ?', DateTime.now.year) } 
# or 
def self.archived 
    joins(:day).where('days.year_id != ?', DateTime.now.year) 
end 
  • プッシュダウンデータベースに現在の年の計算:

    scope :archived, joins(:day).where('days.year_id != extract(year from current_date)') 
    
    1. はスコープのためのクラスメソッドやラムダを使用します。この問題には2つのソリューションがあります。

      データベースの中には、extract(year from current_date)の代わりに何かが必要なものがありますので、wi可能性のある移植性とタイムゾーンの問題を避けるために(1)

      Day.where(...)の部分にも同様の問題があり、アプリケーションの実行中にdaysテーブルが変更された場合は、間違ったリストをチェックすることになります。

    関連する問題