2010-07-13 16 views
12

Corto: Tengo un atributo de clave externa y quiero saber cuál es la clase (o tabla de referencia) de ese campo de clave externa.¿Cuál es la clase de una asociación basada solo en el atributo de clave externa?

Contexto:

dado 2 tablas: users(id, [other fields]) y issues(id, user_id, assigned_to, [other fields])

Aquí está mi registro activo de Emisión (partes irrelevantes se extraen)

class User < ActiveRecord::Base 
    ... 
end 
class Issue < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :assigned_user, :foreign_key => 'assigned_to', :class_name => 'User' 
    ... 
end 

Quiero hacer un usuario puede leer el registro de cambios . p.ej. Al cambiar de usuario asignado, quiero obtener un mensaje como este: Assigned to is changed from Otto to Zoltan. ActiveRecord tiene la función changes, que es un buen punto de partida pero me da únicamente ID-s de referencia. Para traducir a nombres, necesito leer usuario por identificación.

Para la asociación :user es bastante fácil porque tengo que seguir solo las convenciones. Pero, ¿cómo obtener la misma información para el atributo assigned_to (quiero hacer una solución general)? ¿Es posible determinar si tenemos asociación para el atributo dado? ¿Podemos extraer la clase de esa asociación?

Respuesta

3

Gracias. Aquí está la solución final para el problema específico (para aprender):

def textalize_changes 
    if changed? 
     r = "" 
     changes.keys.each do |k| 
     r << "#{k.humanize} changed " 
     r << "from `#{translate(k,changes[k][0])}` " 
     r << "to `#{translate(k,changes[k][1])}`" 
     r << "<br/>" 
     end 
     r 
    end 
    end 

    def translate(attr_name, attr_value) 
    ass = self.class.reflect_on_all_associations(:belongs_to).reject{|a| attr_name != a.primary_key_name} 
    if 1 == ass.length and !attr_value.blank? 
     obj = ass[0].klass.find(attr_value) 
     obj.send(:name) 
    else 
     attr_value 
    end 
    end 
29

Primero, puede usar reflect_on_association para obtener los metadatos de la asociación que desea. Luego, a partir de su resultado (que es un descendiente MacroReflection) se puede averiguar la clase:

reflection = Issue.reflect_on_association(:assigned_user) 
reflection.class # => ActiveRecord::Reflection::AssociationReflection 
reflection.class_name # => 'User' 

Consulte la documentación here y there.

+0

Sus enlaces a documentos no funcionan. Además, ¿hay alguna manera de obtener el espacio de nombre completo? Al igual que 'MyModule :: User' –

+2

ah, puede hacer reflection.klass para obtener el espacio de nombres. –

Cuestiones relacionadas