2010-10-02 8 views
1

J'ai plusieurs modèles avec les colonnes created_by et modified_by. C'est ce que j'ai pour un modèle d'affaire.Rails multiples has_one associations

class Deal 
    has_one :user , :foreign_key => 'created_by' 
    has_one :user , :foreign_key => 'modified_by' 
end 

class User 
    belongs_to :created_by , :class_name => 'Deal' , :foreign_key => 'created_by' 
    belongs_to :modified_by , :class_name => 'Deal' , :foreign_key => 'modified_by' 
end 

Lorsque je crée l'accord, il semble qu'il enregistre correctement. Mais dans la vue d'exposition quand j'essaye d'obtenir @deal.created_by.email j'obtiens une "méthode non définie email" erreur. Est-ce que certains peuvent me dire comment faire fonctionner ça s'il vous plait?

De plus, étant donné que j'ai plusieurs modèles avec ces deux colonnes, il peut y avoir de nombreux modèles appartenant à appartenant au modèle Utilisateur. Y a-t-il une solution élégante pour ce cas?

Répondre

4

La première chose que vous devez ajouter est la spécification des attributs accessibles. Dans utilisateur vous devez ajouter:

attr_accessible :email, :created_by, :modified_by 

Deal:

attr_accessible :created_by, :modified_by 

Mais vous devez aussi changer la direction de votre relation. La clé foreign_key est toujours du côté belongs_to.

C'est ce qui a fonctionné pour moi:

class Deal < ActiveRecord::Base 
    belongs_to :created_by, :class_name => "User", :foreign_key => "created_by" 
    belongs_to :modified_by, :class_name => "User", :foreign_key =>"modified_by" 

    attr_accessible :created_by, :modified_by, :name 
end 

class User < ActiveRecord::Base 
    has_many :created_deals, :class_name => "Deal", :foreign_key => "created_by" 
    has_many :modified_deals, :class_name => "Deal", :foreign_key => "modified_by" 

    attr_accessible :created_deals, :modified_deals, :name 
end 

Si vous avez plus de modèles, qui ont l'air similaire, vous pouvez probablement utiliser des associations polymorphiques: http://guides.rubyonrails.org/association_basics.html#polymorphic-associations

2

Tout d'abord, de mon expérience, il est généralement mauvaise idée d'avoir des associations utilisant la clé étrangère comme nom. Surtout lors de l'écriture d'appareils, il semble que les rails seront confondus entre la définition de la valeur réelle "created_by" ou le modèle dans l'association created_by. Dans mes modèles, j'utilise généralement ces associations pour les cas que vous décrivez:

belongs_to :creator, :class_name => "User", :foreign_key => 'created_by' 
belongs_to :modifier, :class_name => "User", :foreign_key => 'modified_by' 

Vous pouvez utiliser des noms d'associations comme « creating_user » au lieu si vous préférez. Si vous voulez vraiment created_by comme nom d'association, vous devriez avoir created_by_id ou quelque chose de similaire en tant que clé étrangère, aussi longtemps que ce n'est pas égal au nom de l'association.

Ensuite, je suis un peu confus par votre code collé. Votre choix "Deal has_one User" et "User belongs_to Deal" signifie que la table des utilisateurs aura les colonnes created_by et modified_by (clés étrangères) contenant les ID de transaction, ce qui signifie que les utilisateurs seront créés par un accord unique. Cependant, il semble que les offres doivent être créées par les utilisateurs et non l'inverse. Votre exemple de deal.created_by.email ne peut pas fonctionner du tout avec vos associations, car deal n'aurait pas d'association appelée "created_by", seulement "user", dont vous avez deux associations avec le même nom dans un seul modèle qui peut ne fonctionne pas du tout en premier lieu.

Fixation de vos associations similaires à ce que Patrick a suggéré:

class Deal < ActiveRecord::Base 
    belongs_to :creator, :class_name => "User", :foreign_key => "created_by" 
    belongs_to :modifier, :class_name => "User", :foreign_key =>"modified_by" 
end 

class User < ActiveRecord::Base 
    has_many :created_deals, :class_name => "Deal", :foreign_key => "created_by" 
    has_many :modified_deals, :class_name => "Deal", :foreign_key => "modified_by" 
end 
Questions connexes