У меня есть ассоциация has_one, отражающая объекты другой ассоциации. У меня есть Project, в котором есть много ProjectUsers, которые связывают проекты и пользователей. Один из этих ProjectUsers является авторитетным. Проблема в том, что has_one и has_many используют один и тот же внешний ключ для project_users. Вот базовая идея моделей.Переопределение метода присваивания для has_one
class Project < ActiveRecord::Base
has_many :project_users, :class_name => 'ProjectUser', :foreign_key => 'project_id'
has_one :authoritative_user, :class_name => 'ProjectUser', :foreign_key => 'project_id', :conditions => {:authoritative => true}
end
class ProjectUser < ActiveRecord::Base
belongs_to :project
belongs_to :user
# has a boolean column 'authoritative'
end
Что я хотел бы, чтобы иметь возможность позвонить, это что-то типа.
project = Project.new
project_user = ProjectUser.new
project.project_users << project_user
project.authoritative_user = project_user
other_project_user = ProjectUser.new
project.project_users << other_project_user
project.authoriative_user = other_project_user
Где authoritative_user = обновит пользователю проекта, чтобы иметь авторитетное быть установлен так, и сделать предыдущий авторитетный пользователь имеет авторитетное значение ЛОЖЬ. Еще одна проблема, с которой я сталкиваюсь, заключается в том, что во второй раз, когда я устанавливаю authoritative_user в проекте, project_id на предыдущем ProjectUser получает значение nil, и поэтому он больше не связан с Project_users проекта.
Я не уверен, что я просто делаю это совершенно неправильно, или если я просто что-то пропустил.
Мне нравится это решение, если authoritative_user не должен быть изменяемым. Я мог бы даже увидеть, что это работает, если в ProjectUser не было других столбцов для описания пользовательских отношений Project <=>, и поэтому пользователь на AuthoritativeUser мог бы измениться, чтобы определить, кто был авторитетным пользователем, но, к сожалению, есть дополнительные данные. Я мог бы абстрактно выделить все дополнительные метаданные в отдельную модель и просто связать это с ProjectUser/AuthoritativeUser. Я говорю, что потенциально, поскольку для этого случая понадобится массивный страшный рефактор 2-летнего кода. – lambdabutz
Если я чего-то не хватает, authoritative_user, безусловно, может измениться (но может быть только один). Кроме того, нет причин, по которым модель ProjectUser не может иметь дополнительных атрибутов. В конце концов, это по существу, почему существует связь 'has_many: through'. – Brian