ActiveRecord before_findの実装
-
03-07-2019 - |
質問
キーワードをテーブルにキャッシュして検索を構築しています。ユーザーが入力したキーワードは、テーブルで検索される前に正規化されます。たとえば、「-」などの句読点は削除され、大文字と小文字が標準化されます。次に、正規化されたキーワードを使用して、検索結果を取得します。
現在、コントローラーでbefore_filterを使用して正規化を処理しています。代わりにモデルでこれを行う方法があるかどうか疑問に思っていました。概念的に" before_find"のようなものコールバックは機能しますが、インスタンスレベルでは意味がありません。
解決
名前付きスコープを使用する必要があります:
class Whatever < ActiveRecord::Base
named_scope :search, lambda {|*keywords|
{:conditions => {:keyword => normalize_keywords(keywords)}}}
def self.normalize_keywords(keywords)
# Work your magic here
end
end
名前付きスコープを使用すると、他のスコープとチェーンできるようになり、実際にRails 3を使用する方法になります。
他のヒント
おそらくfindをオーバーライドしてこれを実装したくないでしょう。 findのようなものをオーバーライドすることは、おそらく頭を悩ますでしょう。
ただし、次のような必要なことを行うクラスメソッドを作成できます。
class MyTable < ActiveRecord::Base
def self.find_using_dirty_keywords(*args)
#Cleanup input
#Call to actual find
end
end
本当に過負荷にしたい場合は、次の方法で本当に見つけることができます:
例:
class MyTable < ActiveRecord::Base
def self.find(*args)
#work your magic here
super(args,you,want,to,pass)
end
end
チェックアウトのサブクラス化の詳細については、 Rubyのヒント
上記と同様に、 alias_method_chain
も使用できます。
class YourModel < ActiveRecord::Base
class << self
def find_with_condition_cleansing(*args)
#modify your args
find_without_condition_cleansing(*args)
end
alias_method_chain :find, :condition_cleansing
end
end
所属していません StackOverflow