2012-08-16 12 views
39

Quiero agregar a un modelo existente algunos atributos que no necesitan persistir, ni siquiera asignarse a una columna de base de datos. ¿Hay alguna solución para especificar tal cosa?Atributos del modelo de ActiveRecord no persistentes

+0

Posible duplicado de [Agregar atributos at-run adicionales a un objeto activerecord] (http://stackoverflow.com/questions/7584592/adding-extra-run-time-attribs-to-an-activerecord-object) – mlt

Respuesta

48

Por supuesto, use good old ruby's attr_accessor. En su modelo:

attr_accessor :foo, :bar 

podrás hacer:

object.foo = 'baz' 
object.foo #=> 'baz' 
+14

¿Cómo obtener este atributo en el formato JSON del objeto? Diga, quiero que este atributo aparezca en el JSON del objeto en el lado del cliente. ¿Lo conseguiré? a partir de ahora no lo estoy obteniendo, aunque configuré esto en mi método de creación. ¿Cómo hacerlo? – Yash

+0

¿Y en Rails 4? – monteirobrena

+1

@monteirobrena lo mismo – apneadiving

26

que estaba teniendo el mismo problema pero necesitaba para arrancar el modelo, por lo que el atributo tenido que persistir después fue llamado a_json . Necesitas hacer algo extra para esto.

Como señaló apneadiving, la forma más fácil de empezar es ir a su modelo y añadir:

attr_accessor :foo 

A continuación, puede asignar los atributos que desee. Pero para hacer que el atributo se adhiera, debes cambiar el método de los atributos. En su archivo de modelo, agregue este método:

def attributes 
    super.merge('foo' => self.foo) 
end 
1

En mi caso, quería utilizar una combinación izquierda para completar el atributo personalizado. Funciona si no agrego nada, pero también quiero poder establecer el atributo en un nuevo objeto y, por supuesto, no existe. Si agrego attr_accessor, siempre devuelve nil después de select. Este es el enfoque con el que he terminado que funciona para establecer un nuevo objeto y recuperarlo de la combinación de la izquierda.

after_initialize do 
    self.foo = nil unless @attributes.key?("foo") 
end 

def foo 
    @attributes["foo"] 
end 

def foo=(value) 
    @attributes["foo"] = value 
end 
+0

Ya no funciona en Rails 4.2. '@ attributes' ahora es un' ActiveRecord :: AttributeSet' que admite '[]' pero no '[] ='. – davogones

5

En caso de que alguien se pregunta cómo hacen esto a la vista, utilizar los argumentos del método para el método render, así:

render json: {results: results}, methods: [:my_attribute] 

por favor sepa que esto sólo funciona si se establece la attr_accessor en su modelo y establezca el atributo en la acción del controlador, como se explicó en la respuesta seleccionada.

Cuestiones relacionadas