9

名前付きスコープがあると仮定します。

class Foo < ActiveRecord::Base
    named_scope :bar, :conditions => 'some_field = 1'
end

これはクエリに最適で、便利なnamed_scopesがたくさん定義されています。私が望んでいるのは、これを実行できるようにすることです。

f = Foo.find(:first)
f.some_field = 1
f.is_bar? #=> true

バー?' モデルインスタンスが指定されたスコープ内にある場合、メソッドは単にtrueまたはfalseを返します。'is_bar'を記述せずにこれを行う方法はありますか?何かが「is_bar?」であるかどうかをチェックするための良い方法をすでに書いているにもかかわらず、メソッド 私が正しく覚えていれば、DRYは良いので、どんな助けでも大歓迎です/

4

2 に答える 2

25

名前付きスコープでメソッドを呼び出すとexists?、データベースにクエリを実行して、指定されたレコードがこれらの条件で存在するかどうかを確認できます。

Foo.bar.exists?(f)

ただし、属性を変更fしてデータベースに保存していない場合、これは機能しません。これは、名前付きスコープの条件がSQLであるため、そこでチェックを実行する必要があるためです。if特により複雑なシナリオでは、Ruby条件に変換しようとするのは面倒です。

于 2009-08-10T16:41:03.973 に答える
0

スコープが単純な場合は、コードの重複を避けたいと思うでしょう。私のソリューションではmodel.active?、インスタンスを呼び出してスコープに属しているかどうかを確認し、スコープにModel.active一致するすべてのレコードを見つけることができます。model.active?データベースクエリは含まれません。

これをに追加することを検討してconfig/initializers/scope_and_method.rbください:

require 'active_record/named_scope'

module ActiveRecord::NamedScope::ClassMethods
  def scope_and_method field, *values
    field = field.to_sym
    values.each do |value|
      named_scope value.to_sym, :conditions => {field => value}
      define_method "#{value}?" do
        send(field.to_sym) == value
      end
    end
  end
end

使用法:

scope_and_method :state, 'active', 'inactive'

それがそうであったかのように動作します:

named_scope :active, :conditions => {:state => 'active'}
named_scope :inactive, :conditions => {:state => 'inactive'}

def active?
  state == 'active'
end

def inactive?
  state == 'inactive'
end

これはRails2.3のソリューションです。これには、Rails 3と4の非常に小さな調整が必要です。(named_scope-> scope)すぐに確認します。

于 2013-12-18T14:12:36.207 に答える