I have a has_one association that is reflective on the objects of another association. I have Project, which has many ProjectUsers, which tie Projects and Users. One of those ProjectUsers is authoritative. The issue is that both the has_one and the has_many use the same foreign key on project_users. Here's the base idea of the models.
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
What I would like to be able to do is call something like.
project = Project.new
project_user = ProjectUser.new
project.project_users << project_user
project.authoritative_user = project_user
other_project_user = ProjectUser.new
projec开发者_StackOverflowt.project_users << other_project_user
project.authoriative_user = other_project_user
Where authoritative_user= would update the project user to have authoritative be set to true, and make the previous authoritative user have authoritative set to false. Another issue I am having is that second time I set authoritative_user on the project, project_id on the previous ProjectUser gets set to nil, and so it is no longer associated though the Project's project_users.
I'm not sure if I'm just doing this completely wrong, or if I'm just missing something.
class Project < ActiveRecord::Base
has_many :project_users
has_many :users, :through => :project_users
belongs_to :authoritative_project_user, :class_name => 'ProjectUser'
has_one :authoritative_user, :through :authoritative_project_user
end
class ProjectUser < ActiveRecord::Base
belongs_to :project
belongs_to :user
has_one :project_as_authorized_user
end
then just let the has_one project_as_authorized_user relationship nil out your belongs_to authorized_project_user
Personally, I'd probably look to simplify/separate concerns. Here is an example (note: untested):
class Project < ActiveRecord::Base
has_many :project_users
has_many :users, :through => :project_users
has_one :authoritative_user
end
class ProjectUser < ActiveRecord::Base
belongs_to :project
belongs_to :user
end
class AuthoritativeUser < ActiveRecord::Base
belongs_to :project
belongs_to :user
validates_uniqueness_of :user_id, :scope => :project_id
end
Essentially, I break out the authoritative_user
attribute of your ProjectUser
model into it's own. Very simple, clean and not very exciting.
You could probably build a few convenience methods like has_authoritative_user?
and update_authoritative_user
in your Project
model.
I'm sure you'll get a few better suggestions.
Hope this helps!
精彩评论