2012-05-29 19 views
6

Usando Rails 3.2.3, tengo modelos de Usuario y Mensaje. Cada mensaje es propiedad de un usuario, y cada mensaje tiene un campo opcional from_user que también toma un user.id.Rieles ActiveRecord crea una clave externa incorrecta si hay dos relaciones belongs_to con el mismo modelo

app/modelos/user.rb

class User < ActiveRecord::Base 
    has_many :messages, :foreign_key => "owner_id",  :inverse_of => :owner 
    has_many :messages, :foreign_key => "from_user_id", :inverse_of => :from_user 
end 

app/models/message.rb

class Message < ActiveRecord::Base 
    belongs_to :owner, :class_name => "User", :inverse_of => :messages 
    validates :owner, :presence => true # Every message must have an owner_id 

    belongs_to :from_user, :class_name => "User", :inverse_of => :messages 
end 

El problema que estoy viendo es el método .build. La razón principal para usar .build es crear una instancia de una clave foránea (posiblemente protegida), ¿verdad? (Véase la Rails Guide en asociaciones Active Record: "el enlace a través de su clave externa se creará.") Sin embargo cuando corro

@message = @user.messages.build(<accessible attributes>) 

Me parece que se está llenando en el opcional from_user y no la obligatoria owner .

¿Hay alguna forma de controlar qué clave externa .build rellena? ¿O necesito simplemente usar .new y asignar todas las claves foráneas manualmente?

@message = Message.new(<accessible attributes>) 
@message.owner = @user 
@message.from_user = @another_user 

Respuesta

5

ActiveRecord does like that usted tiene 2 asociaciones con el mismo nombre. Vas a tener que cambiar los nombres de la asociación. Esto significa que también deberá proporcionar el atributo class_name. Tal vez algo así como:

has_many :owner_messages, :class_name => 'Message', :foreign_key => "owner_id",  :inverse_of => :owner 
has_many :user_messages, :class_name => 'Message', :foreign_key => "from_user_id", :inverse_of => :from_user 
+1

Gracias, en el clavo. Y luego es '@ user.owner_messages.build ()' para construir. Me pregunto por qué, si Rails requiere nombres de asociación únicos, no se queja cuando no son únicos. Aparentemente solo usa la última definición: si hubiera definido 'has_many: messages,: foreign_key =>" owner_id "' segundo, nunca lo habría visto. –

+0

Acabo de darme cuenta de que los nombres ': inverse_of' deben cambiar en las líneas' belongs_to'. 'belongs_to: owner,: class_name =>" User ",: inverse_of =>: owner_messages' y' belongs_to: from_user,: class_name => "User",: inverse_of =>: user_messages'. –

Cuestiones relacionadas