12

我有一个User模型有许多projectsProject模型,它可以有很多users,但也属于单个用户(即创建此项目的用户)。它必须属于User。它还允许用户列表与之相关联,思考协作。导轨有很多,属于一个

考虑到这一点,我的模型是这样的:

class User < ActiveRecord::Base 
    has_many :assigned_projects 
    has_many :projects, :through => :assigned_projects 
end 

class Project < ActiveRecord::Base 
    belongs_to :user 
    has_many :assigned_projects 
    has_many :users, :through => :assigned_projects 
end 

class AssignedProject < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :project 
end 

现在,当我想通过一个User创建一个新的项目,这是我会怎么做:

user = User.create(:name => 'injekt') 
user.projects.create(:name => 'project one') 

现在,我知道projects通过一个AssignedProject提供加盟的模式,这就是为什么project.user将返回nil。我挣扎,围绕让我的头是分配项目创建者(其中的方式做的最好办法不是需要user,也可能是creator或别的东西,描述性的,只要它的类型User)。

然后,这个想法是创建一个方法,从User返回projects_created,它将只选择由该用户创建的项目。其中user.projects当然会返回用户所关联的所有项目。

假设这种关联是相当常见的,什么是实现我想要的东西的最佳方式?任何方向都不胜感激。

回答

20

到项目表中添加creator_id列的创造者的关系,然后添加协会机型:

class User < ActiveRecord::Base 
    has_many :assigned_projects 
    has_many :projects, :through => :assigned_projects 

    has_many :created_projects, :class_name => "Project", :foreign_key => :creator_id 
end 

class Project < ActiveRecord::Base 
    belongs_to :user 
    has_many :assigned_projects 
    has_many :users, :through => :assigned_projects 

    belongs_to :creator, :class_name => "User", :foreign_key => :creator_id 
end 

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many

+0

感谢您的回答,但这不是我的问题。它是:*什么我挣扎,周围让我的头是分配项目创建者(其中的方式并不需要是用户的最佳途径,也可能是创作者还是其他什么东西的描述,只要它是类型的用户)。* –

+0

@Nuby肯定什么?当然,我正努力让自己的头脑以自动化的方式将用户/创建者分配给项目?是的 –

+0

除非我误读@ Pavling的回答(和你的问题),他所建议的是你与用户表创建第二种关系,称为'创造者'。然后你可以调用'Project.creator'从'CreatedProjects'关联中获取关联的用户。这将解决(我认为)你的问题。至于如何分配它,你可以在模型中做一个'before_create'钩子,将其分配给当前登录的用户或其他用户(取决于你的项目逻辑)。 – Nuby

1

我想补充一点的改进设计。我们实际上并不需要中间模型,因为它不包含reference_ids以外的任何额外列,因此HABTM关联最适合在这里使用。

class User < ActiveRecord::Base 
    has_and_belongs_to_many :projects, :join_table => :assigned_projects 
    has_many :created_projects, :class_name => "Project", :foreign_key => :creator_id 
end 

class Project < ActiveRecord::Base 
    has_and_belongs_to_many :users, :join_table => :assigned_projects 
    belongs_to :creator, :class_name => "User", :foreign_key => :creator_id 
end 
+0

真的吗?您不关心用户在给定项目上分配了什么角色,或者他们的任务日期是什么,或者与该用户参与该特定项目相关的任何其他信息?您将在本月底之前将该HABTM重构为HMT ;-) – Pavling

+0

@收集您所说的用户角色?我不会让你这样。是否有需要完成项目任务的日期?如果额外的列将在那里,那么'has_many through'可能是不错的选择。 –

+1

在一个项目上,用户可能担任技术主管的角色,在另一个项目上,她可能是一个UI测试人员。你可能不想要这个特定的信息(或者任务日期) - 这只是一个例子;但是你*会*需要更多的信息,而不仅仅是*谁在项目中。当然,HABTM类型关系确实有它们的位置,但实际上,*这个*是一个HMT。 – Pavling