Agregar una opción case_sensitivity a los métodos find_by_x sin código duplicado

Quiero poder hacer Post.find_by_slug('some-slug', :case_sensitive => false), Post.find_by_title('some title', :case_sensitive => false).

I've tried the following 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

¿Cómo puedo conseguir el :case_sensitive => false option for all the find_by_x methods without duplicate code?

preguntado el 08 de enero de 11 a las 22:01

1 Respuestas

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)

Respondido el 09 de enero de 11 a las 04:01

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.