Rails множественные ассоциации has_one - PullRequest
1 голос
/ 02 октября 2010

У меня есть несколько моделей со столбцами созданных и измененных.Это то, что у меня есть для модели сделки.

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

Когда я создаю сделку, похоже, что она сохраняется правильно.Но в представлении show, когда я пытаюсь получить @deal.created_by.email, я получаю ошибку "undefined method email".Может кто-нибудь сказать мне, как заставить это работать, пожалуйста?

Кроме того, поскольку у меня есть несколько моделей с этими двумя столбцами, в модели пользователя может быть много принадлежностей.Есть ли элегантное решение для этого случая?

Ответы [ 2 ]

4 голосов
/ 10 октября 2010

Первое, что вы должны добавить, это спецификация доступных атрибутов. В User вы должны добавить:

attr_accessible :email, :created_by, :modified_by

В сделке:

attr_accessible :created_by, :modified_by

Но вы также должны изменить направление своих отношений. Foreign_key всегда находится на стороне принадлежащей стороне.

Вот что у меня сработало:

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

Если у вас есть больше моделей, которые похожи, вы, вероятно, могли бы использовать полиморфные ассоциации: http://guides.rubyonrails.org/association_basics.html#polymorphic-associations

2 голосов
/ 12 февраля 2011

Прежде всего, исходя из моего опыта, вообще плохая идея иметь ассоциации, использующие внешний ключ в качестве имени.Особенно при написании осветителей кажется, что рельсы могут запутаться между установкой фактического значения «create_by» или модели в ассоциации созданной_by.В моих моделях я обычно использую эти ассоциации для описываемых вами случаев:

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

Вместо этого вы можете использовать имена ассоциаций, такие как «creation_user», если хотите.Если вы действительно хотите, чтобы в качестве имени ассоциации был создан create_by, то вы должны иметь значение create_by_id или что-то похожее на внешний ключ, если оно не совпадает с именем ассоциации.

Тогда я немного смущен вашим вставленным кодом.Ваш выбор "Deal has_one User" и "User assign_to Deal" означает, что таблица пользователей будет иметь столбцы созданных_данных и модифицированных_безопасных (внешние ключи), содержащие идентификаторы сделок, в основном это означает, что пользователи создаются одной сделкой?Однако кажется, что сделки должны создаваться пользователями, а не наоборот.Ваш пример deal.created_by.email может вообще не работать с вашими ассоциациями, так как в сделке не будет ассоциации с именем "creation_by", только "пользователь", из которой у вас есть две ассоциации с одним и тем же именем в одной модели, которая можетвообще не работает вообще.

Исправление ваших ассоциаций похоже на то, что предложил Патрик:

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
...