9

現在保存中に、記録が特定の「スコープ」に該当するかどうかを確認しようとしています。この「スコープ」は、実際には .where 呼び出しの保存された引数にすぎません。また、この「スコープ」を使用すると、オブジェクトの値をチェックするだけで、データベース内の他のオブジェクトとの関係をチェックすることはありません。

私は以下の解決策しか思いつかなかった

begin
   result = self.class.where(scope).find(self.id)
rescue
  result = false
end

これに関する問題は、既にレコードがあるにもかかわらず、データベースにクエリを実行する必要があることです。保存前だけでなく、保存後にこれを実行して、以前の値と保存後の値を確認する必要があります。保存されていない場合、更新されたバージョンをデータベースに照会する方法はありません。

これらのチェックは多数ある可能性があるため、最終的にIDで何かを検索するだけであっても、2回実行したり、データベースに何度もクエリを実行したりすることは避けたいと思います.

私が考えることができた他の唯一の解決策は、オブジェクトが渡されたときにブール値を返すprocにwhere呼び出しを何らかの方法で変換するメソッドを持つことです。それに関する唯一の問題は、使用されているアクティブなレコード アダプターとどのように連携する必要があるかということです。これは、プロジェクト全体のように見えます。それで、これを行う方法、または役立つgemを知っている人はいますか?

PSキャッシュから「スコープ」を取得しているため、Railsを使用してprocをキャッシュに入れることができないため、procとして保存できません。

4

2 に答える 2

6

まず、最初のソリューションを少し改善できます

result = self.class.where(scope).exists?(self.id)

データベースをチェックしたくない場合は、オブジェクトの属性にスコープの値があるかどうかをチェックしてみませんか?スコープが

class.where(:attr1 => value1, :attr2 => value2, :attr3 => value3)

その後、あなたはすることができます

result = self.attr1 == value1 and self.attr2 == value2 and self.attr3 == value3
于 2012-07-30T02:58:29.490 に答える
4

スコープが単純な場合は、おそらくコードの重複を避けたいでしょう。私のソリューションでは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

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

于 2013-12-18T14:07:26.903 に答える