Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top