これは動作します:Rails 3スコープ内にIN句を書く最も良い方法は?
scope :archived, :conditions => "day_id IN (#{Day.where("year_id != #{DateTime.now.year}").collect{ |d| d.id }.join(",")})"
句で書くためのより多くのrailsy方法はありますか?
これは動作します:Rails 3スコープ内にIN句を書く最も良い方法は?
scope :archived, :conditions => "day_id IN (#{Day.where("year_id != #{DateTime.now.year}").collect{ |d| d.id }.join(",")})"
句で書くためのより多くのrailsy方法はありますか?
あなたは
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
このようなことはできますか?
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
を置き換えます。簡単な再書き込みについては
元の範囲と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)')
はスコープのためのクラスメソッドやラムダを使用します。この問題には2つのソリューションがあります。
データベースの中には、extract(year from current_date)
の代わりに何かが必要なものがありますので、wi可能性のある移植性とタイムゾーンの問題を避けるために(1)
Day.where(...)
の部分にも同様の問題があり、アプリケーションの実行中にdays
テーブルが変更された場合は、間違ったリストをチェックすることになります。
完璧な、これは私が探していたものです、ありがとう! –
あなたは隠れたバグを見落としました。 ModelクラスがDec31の23:00にロードされ、スコープがJan1の02:00に使用されるとどうなりますか? –