2
は、このモデルを与えられた:それはactive?
方法で条件を繰り返さないため 他の方法でレール範囲条件を再利用するためのDRYソリューション? Railsの3.1に
class Subscripion < ActiveRecord::Base
scope :active, lambda {
where("start_date is not ? AND end_date >= ?", nil, Date.today)
}
def active?
self.class.active.exists?(self)
end
end
はこれまでのところ、これは、私は考えることができ、乾燥-estのソリューションです。
2つの欠点は、しかしあります
- は、サブスクリプションのインスタンスを考えると、何のデータベースクエリは、それがアクティブであるかどうかを決定するために必要ないであろう。その属性に基づいて確認できます:
!start_date.nil? && end_date >= Date.today
。exists?
を呼び出すと、追加のデータベースクエリが発生します。 exists?
スコープのexists?
を呼び出す前に最初のサブスクリプションインスタンスを変更した場合、exists?
はインスタンスを無視してデータベースに直接クエリを実行するので、結果は必要ではありません。
さらに良いソリューションについてのアイデアは、1つの場所で条件を定義していますか?
提案しているように 'where(id:self.id).present? 'を使うのはやや効率的ですが、唯一の違いは結果の行のすべての属性ではなく、カウントを返すことです。 '存在しますか?(自己)'はすべてのアクティブなサブスクリプションを最初にロードしません。 'SELECT COUNT(*)'の代わりに 'SELECT 1 FROM ... LIMIT 1'というクエリを出すという点を除いて、ほとんど同じクエリを実行します。 私は、 '!start_date.nil? && end_date> = Date.today'は 'active?'メソッドにとって最も正しいですが、スコープに対して同じ条件を2回定義します。これは、将来エラーが発生しやすくなります。 –