开发者

Adding a case_sensitivity option to find_by_x methods without duplicate code

开发者 https://www.devze.com 2023-02-03 18:30 出处:网络
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 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)
0

精彩评论

暂无评论...
验证码 换一张
取 消