2012-02-11 12 views
5

que tienen un módulo que estoy incluyendo en varios modelos con este contenido:¿Cómo utilizar siempre la clase base e ignorar STI en los rieles?

self.class.find_by_foo(bar) 

Todo estaba bien hasta que empecé a usar STI. Esa línea siempre debe generar la consulta

select * from table where foo=bar" 

y no

select * from table where foo=bar AND type="Whatever" 

¿Existe una manera sencilla de evitarlo?

Pensé en dos soluciones. Subiendo por la jerarquía de clases hasta que encuentre el más alto-clase antes ActiveRecord::Base o ejecutar la consulta con la mano, como:

self.class.find_by_sql("select * from #{self.class.table_name} where foo=bar") 

No me gusta cualquiera de las soluciones. Hay alguno mejor?

Respuesta

2

Hasta que no haya una respuesta mejor, estoy usando este código para encontrar la clase base de la cadena de ITS:

klass = self.class 
self.class.ancestors.each do |k| 
    if k == ActiveRecord::Base 
    break # we reached the bottom of this barrel 
    end 
    if k.is_a? Class 
    klass = k 
    end 
end 
19

En primer lugar, siempre se puede llegar a la clase base con los BASE_CLASS método:

self.class.base_class.find_by_foo(bar) 

Sin embargo, en su ejemplo anterior, no debería tener que acceder a la clase base. Usted sólo puede hacer lo siguiente y rieles conocerá el nombre de la tabla correcta:

self.class.where(:foo => bar) 

En realidad, hay muy pocos casos, es necesario acceder a la clase base.

+0

En Rails 4 'self.class' devolvió inesperadamente la clase padre de los objetos, en Rails 5' self.class' returns, como excepción, la clase de modelos. 'self.class.base_class' se puede usar para obtener la clase padre. – Kris

Cuestiones relacionadas