Ruby metaprogramming: search for users with Person.arbitrary_name
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

I have a Person model in my Rails app. Right now, I can search for people with Person.find(:conditions => [ 'lower(name) = ?', 'john' ]). That's all well and good, but a little unwieldy on the command line. I'd like to be able to just do Person.john and have that return an array of people with name of John.

I obviously don't want to override existing class methods. So I wouldn't be able to use this technique for People named 'count' or 'find_by_weight'.

Please provide the code to do this, in a complete Ruby class for a basic Person model (that extends ActiveRecord).

Edit: prefixing with Person.named_john to avoid collisions is also ok.

Thanks!

awarded to apples

Crowdsource coding tasks.

1 Solution

Winning solution

class Person < ActiveRecord::Base
  def self.method_missing(name, *params)
    Person.find(:all, :conditions => [ 'lower(name) = ?', name])
  end
end

Assuming you are using Rails 2 by your use of find(:conditions), so I couldn't test the find syntax. If your old query was returning all johns, and not just one, remove the :all param from Person.find

Replacement method if using prefix:

def self.method_missing(name, *params)
  if name =~ /^named_/
    name.gsub!(/^named_/, '')
    Person.find(:all, :conditions => [ 'lower(name) = ?', name])
  else
    super
  end
end
Works great! Just had to make a small change to the second part of the solution to get it working (name.gsub! didn't work because name is a symbol)
bevan 9 years ago