I want to be able to do Post.find_by_slug('some-slug', :case_sensitive => false)
, Post.find_by_title('some title', :case_sensitive => false)
.
I've tried the followin开发者_如何学JAVAg approach, but there's a lot of duplicated logic:
def self.find_by_name(name, options = {})
conditions = options[:case_sensitive] == false ? ['UPPER(name) = UPPER(?)', name] : ['name = ?', name]
first(:conditions => conditions)
end
def self.find_by_slug(slug, options = {})
conditions = options[:case_sensitive] == false ? ['UPPER(slug) = UPPER(?)', slug] : ['slug = ?', slug]
first(:conditions => conditions)
end
How can I get the :case_sensitive => false
option for all the find_by_x
methods without duplicate code?
To me, this sounds like an excellent opportunity to use method_missing
. Basically, we'll implement a class method that listens to any method that doesn't already exist on the class.
It can look something like this:
def self.method_missing(method, *args, &block)
if method.to_s =~ /^find_by_(.*)$/
condition = args.first
options = args.last
first(options[:case_sensitive] == false ? ["UPPER(#{$1}) = UPPER(?)", condition] : ["#{$1} = ?", condition])
else
super
end
end
Now, you should be able to do:
find_by_name('name', :case_sensitive => false)
find_by_slug('slug', :case_sensitive => false)
find_by_any_other_column('value', :case_sensitive => false)
精彩评论