2011-09-01 20 views
9

mi configuración: Carriles 3.0.9, Ruby 1.9.2Rails 3 agregar atributo virtual dinámica

tengo mis razones para hacer esto, pero lo que necesitamos es una manera de añadir un atributo virtual a un conjunto de resultados activerecord dinámicamente. Eso significa que no estoy usando attr_accessor en el modelo y en su lugar deseo agregar dinámicamente atributos virtuales a un conjunto de resultados.

Por ejemplo,

users = User.all 
#a user has following attributes: name, email, password 

Lo que me gusta hacer es decir add (sin utilizar attr_accessor) un atributo virtual status a users, es posible?

Respuesta

15

Usted debe hacer esto:

users.each do |user| 
    user.instance_eval do 
    def status 
     instance_variable_get("@status") 
    end   
    def status=(val) 
     instance_variable_set("@status",val) 
    end 
    end 
end 
+0

esto no funcionaría, ya que este atributo no se mantendría en la base de datos – Tilo

+6

@Tilo: obviamente no sabe qué es un atributo virtual – apneadiving

+0

@Tilo: http://railscasts.com/episodes/16-virtual -attributes Verás que un atributo virtual no se debe guardar en la base de datos – apneadiving

2

puede hacer lo siguiente:

añadir un atributo "extras" que se puede acceder como un hash, y el cual almacenará cualquier atributo adicional/dinámicos - - y luego decirle rieles para persistir a través de JSON que Hash en ActiveRecord o Mongo o lo utiliza

por ejemplo:

class AddExtrasToUsers < ActiveRecord::Migration 
    def self.up 
    add_column :users, :extras, :text # do not use a binary type here! (rails bug) 
    end 
    ... 
end 

luego, en el modelo, agregue una instrucción para "serializar" ese nuevo atributo, p. Ej. Eso significa que es persistido como JSON

class User < ActiveRecord::Base 
... 
serialize :extras 
... 
end 

Ahora puede hacer esto:

u = User.find 3 

    u.extras[:status] = 'valid' 
    u.save 

También puede añadir un poco de magia para el modelo de usuario, para mirar el Hash extras si se pone un method_missing() llamar

Ver también: Google "Rails 3 serializar"

+0

no está definiendo un comportamiento 'attr_accessor' aquí. – apneadiving

+0

vuelve a leer la pregunta de Bob - explícitamente dice que no quiere usar attr_accessor – Tilo

+0

, dice que no quiere establecer 'attr_accessor' en el modelo, que es bastante diferente – apneadiving

1

Si sus atributos son de sólo lectura, también se puede añadir mediante la selección de ellos en su base de datos de Quer y Los campos que aparecen en el resultado del resultado de SQL se agregarán automáticamente como atributos.

Ejemplos:

User.find_by_sql('users.*, (...) AS status') 
User.select('users.*, joined_table.status').join(...) 

Con estos ejemplos se tendrán todos los atributos y User un atributo adicional status.

1

simplemente podría hacer:

users.each { |user| user.class_eval { attr_accessor :status } } 

Todo users tendrá user.status y user.status = :new_status disponible.