开发者

Overriding the assignment method for a has_one

开发者 https://www.devze.com 2023-01-17 06:37 出处:网络
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 authoritati

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!

0

精彩评论

暂无评论...
验证码 换一张
取 消