5

カスタム検索条件を設定する必要があるモデルがいくつかあります。たとえば、Contactモデルがある場合、Contact.findが呼び出されるたびに、使用中のアカウントにのみ属する、返される連絡先を制限したいと思います。

私はこれをグーグルで見つけました(私は少しカスタマイズしました):

def self.find(*args)
  with_scope(:find => { :conditions =>  "account_id = #{$account.id}" }) do
    super(*args)
  end
end

account_idがあいまいな場合を除いて、これはうまく機能するので、次のように調整しました。

def self.find(*args)
  with_scope(:find => { :conditions =>  "#{self.to_s.downcase.pluralize}.account_id = #{$account.id}" }) do
    super(*args)
  end
end

これもうまくいきますが、DRYにしたいです。今、私はこの種の関数を使用したいいくつかの異なるモデルを持っています。これを行うための最良の方法は何ですか?

あなたが答えるとき、私たちの心がメタプログラミングRuby-fuを理解するのを助けるためにコードを含めてください。

(私はRails v2.1を使用しています)

4

3 に答える 3

8

使用しているレールのバージョンは教えてくれません [編集 - レール 2.1 にあるため、次のアドバイスは完全に機能します]。

account.contacts.find(...) 

これにより、ユーザー句が含まれるスコープで検索が自動的にラップされます(account_idがあるため、近い場所にアカウントがあると想定しています)

スコープに関する次のリソースを確認することをお勧めします

于 2008-09-17T06:05:55.047 に答える
5

ジャンのアドバイスは適切です。モデルが次のようになっていると仮定します。

class Contact < ActiveRecord::Base
  belongs_to :account
end

class Account < ActiveRecord::Base
  has_many :contacts
end

contacts次のように、現在のアカウントの関連付けを使用して、Contactそのアカウントに限定されたレコードのみを取得していることを確認する必要があります。

@account.contacts

連絡先クエリにさらに条件を追加する場合は、find を使用して指定できます。

@account.contacts.find(:conditions => { :activated => true })

また、アクティブなユーザーを常にクエリしていることに気付いた場合は、それを名前付きスコープにリファクタリングできます。

class Contact < ActiveRecord::Base
  belongs_to :account
  named_scope :activated, :conditions => { :activated => true }
end

次に、次のように使用します。

@account.contacts.activated
于 2008-09-17T13:13:27.953 に答える
0

問題に具体的な答えを出すには、上記の方法をモジュールに移動して、問題のモデルに含めることをお勧めします。だからあなたは持っているだろう

class Contact
  include NarrowFind
  ...
end

PS。account_id の sql エスケープに注意してください。おそらく:conditions=>[".... =?", $account_id]構文を使用する必要があります。

于 2008-09-17T06:50:11.383 に答える