2012-05-29 12 views
6

Używanie Rails 3.2.3, Mam modele User i Message. Każda wiadomość jest własnością użytkownika, a każda wiadomość ma opcjonalne pole od_użytkownika, które również pobiera user.id.Rails ActiveRecord buduje niepoprawny klucz obcy, jeśli istnieją dwa relacje belongs_to z tym samym modelem

app/models/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 

Problem widzę jest metodą .build. Głównym powodem użycia .build jest utworzenie (prawdopodobnie chronionego) klucza obcego, prawda? (Patrz Rails Guide na aktywnych stowarzyszeń rekord: „link poprzez ich klucz obcy zostanie utworzony”). Jednak gdy uruchamiam

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

uważam, że jest wypełnienie w opcjonalnym from_user i nie obowiązkowe owner .

Czy istnieje jakiś sposób kontrolowania, który klucz obcy .build wypełnia? Czy muszę po prostu użyć .new i ręcznie przypisać wszystkie klucze obce?

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

Odpowiedz

5

ActiveRecord nie sprawia, że ​​masz 2 skojarzenia o tej samej nazwie. Będziesz musiał zmienić nazwy skojarzeń. Oznacza to, że będziesz również musiał dostarczyć adresatowi class_name. Może coś takiego:

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

Dzięki, miejsce na. Następnie budujemy "@ user.owner_messages.build ()". Zastanawiam się, dlaczego, jeśli Railsy wymagają unikalnych nazw skojarzeń, nie narzeka, gdy nie są unikatowe? Najwyraźniej po prostu używa ostatniej definicji - gdybym zdarzyło mi się zdefiniować 'has_many: messages,: foreign_key =>" owner_id "' sekunda, nigdy bym tego nie widział. –

+0

Po prostu zdałem sobie sprawę, że nazwy ': inverse_of' muszą się zmienić w liniach' belongs_to'. 'belongs_to: owner,: class_name =>" User ",: inverse_of =>: owner_messages' i' belongs_to: from_user,: class_name => "User",: inverse_of =>: user_messages'. –