Implementing an ActiveRecord before_find

2019-05-10 22:03发布

I am building a search with the keywords cached in a table. Before a user-inputted keyword is looked up in the table, it is normalized. For example, some punctuation like '-' is removed and the casing is standardized. The normalized keyword is then used to find fetch the search results.

I am currently handling the normalization in the controller with a before_filter. I was wondering if there was a way to do this in the model instead. Something conceptually like a "before_find" callback would work although that wouldn't make sense on for an instance level.

3条回答
在下西门庆
2楼-- · 2019-05-10 22:19

You probably don't want to implement this by overriding find. Overriding something like find will probably be a headache down the line.

You could create a class method that does what you need however, something like:

class MyTable < ActiveRecord::Base
  def self.find_using_dirty_keywords(*args)
    #Cleanup input
    #Call to actual find
  end
end

If you really want to overload find you can do it this way:

As an example:

class MyTable < ActiveRecord::Base
  def self.find(*args)
    #work your magic here
    super(args,you,want,to,pass)
  end
end

For more info on subclassing checkout this link: Ruby Tips

查看更多
淡お忘
3楼-- · 2019-05-10 22:20

much like the above, you can also use an 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
查看更多
淡お忘
4楼-- · 2019-05-10 22:30

You should be using named scopes:

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

Using named scopes will allow you to chain with other scopes, and is really the way to go using Rails 3.

查看更多
登录 后发表回答