有很多通过关联回调与多个关联使用相同的连接表

时间:2012-02-04 00:51:05

标签: ruby-on-rails ruby-on-rails-3 callback model-associations

所以这可能是非常糟糕的形式。我对铁杆比较陌生。我不确定。

我有一个项目模型,我希望有很多所有者(可以读写所有内容)和许多合作者(可以读写一些东西)。

在我的project.rb文件中,我有:

  has_many :project_user_relationships, :dependent => :destroy
  has_many :collaborators, :through => :project_user_relationships, :source => :user

  has_many :project_owners_relationships, :class_name => "ProjectUserRelationship", :foreign_key => "project_id", 
           :before_add => Proc.new { |p,owner_r| owner_r.owner = true }, :conditions => "`project_user_relationships`.owner = true"
  has_many :owners, :through => :project_owners_relationships, :source => :user

所以这个工作得相当好。如果我添加新的所有者,该用户也是我想要的协作者。我不确定如何解决的问题是,如果我添加一个已经是协作者的用户作为所有者,我在连接表中得到两个条目。我想它只是修改已经存在的记录。我该怎么做?

1 个答案:

答案 0 :(得分:1)

以下是我建议的数据模型:

class Project < ActiveRecord::Base
    has_many :memberships, :dependent => :destroy
    ...
end

class Membership < ActiveRecord::Base
    belongs_to :project
    belongs_to :user
    ...
end

class User < ActiveRecord::Base
    has_many :memberships, :dependent => :destroy
    has_many :projects, :through => :memberships
    ...
end

然后,成员资格表将具有以下属性:

:id
:user_id
:project_id
:is_owner (boolean)

在会员类上定义的范围:

scope :owner, where("is_owner")

用户实例的特殊方法:

def owned_projects
    memberships.owner.includes(:projects).inject([]) {|array, m| array << m.project; array}
end

允许您使用user.owned_projects调用来检索用户拥有的项目。

只需调用user.projects即可查看用户协作或拥有的项目。

您可以使用此数据模型进行更好的数据规范化,并使用简单的布尔属性来定义用户是否为项目所有者。

此数据模型在this project中使用,但s / Project / Group /除外,还有一些其他功能可以处理邀请用户加入项目。

这不能解答您的“真实问题”,但我认为部分问题是需要将协作者所有者存储在同一个表中的数据模型,以最大限度地减少冗余并管理两个单独的表。