2009-08-07 20 views
27

Tengo una aplicación de rieles con varios modelos.Dónde poner las funciones de "utilidad" del modelo en Ruby on Rails

Tengo una función a la que quiero acceder desde varios modelos.

¿Cuál es el mejor lugar para poner este código y cómo puedo hacerlo accesible desde los modelos que necesitan obtenerlo?

Según tengo entendido, los helpers son solo para visitas. ¿Es esto correcto?

Parece incorrecto crear un complemento y ponerlo en la carpeta del proveedor: este es mi código y es parte integrante de mi aplicación. ¿Es esto correcto?

Gracias.

Respuesta

30

La solución más sencilla sería la creación de un módulo en lib y mezclar esto en los modelos que lo necesitan, por ejemplo, en lib/fooable.rb:

module Fooable 
    def do_foo 
    end 
end 

Y luego, en sus diversos modelos:

class MyModel < ActiveRecord::Base 
    include Fooable 
end 

No hay necesidad de requerir fooable.rb, el mecanismo de carga automática rieles lo encontrará para usted, siempre y cuando se nombra utilizando las convenciones correctas.

+0

Rails 4: incluso no funcionó para mí, pero sí lo requería. También tuve que llamar a la función de esta manera: Fooable.function – reectrix

+1

@smilingcow Es la cuestión de la configuración desde 'rails 3 '. Vea [esto] (http://stackoverflow.com/a/5273470/535406) ​​respuesta para más detalles. – jibiel

+3

Cosas como esta pongo/model/concerns (si solo es para extender modelos) pero para las clases de utilidad las pongo en lib/utils (lib puede llenarse) – Aeramor

2

Para disminuir la repetición del código, también puede crear una clase principal que incluya ese módulo y heredar simplemente de cada modelo que desee compartir el comportamiento.

Algo así como:

module Fooable 
    def do_foo 
    end 
end 

class ParentModel < ActiveRecord::Base 
    include Fooable 
end 

class Product < ParentModel end 
class User < ParentModel end 
class Item < ActiveRecord::Base end 

Por lo tanto, en este ejemplo, tanto el producto como usuario compartiría la funcionalidad y do_foo artículo no lo haría.

+11

Esto funciona, por supuesto, pero me pregunto si la eliminación de la repetición vale la pena ensuciar la cadena de herencia; podría argumentar que esto es exactamente lo que los módulos ayudan a evitar: herencia innecesaria. ¿Está tratando de evitar las múltiples declaraciones include que toman DRY un paso demasiado lejos? Creo que podría ser. –

+1

Esto también causará problemas cuando su ParentModel tenga una columna de cadena llamada "tipo" en la base de datos, ya que esto causará [herencia de tabla única] (http://api.rubyonrails.org/classes/ActiveRecord/Base.html#class -ActiveRecord :: Base-label-Single + table + inheritance) para iniciar. –

Cuestiones relacionadas