【问题标题】:Rails has many and belongs to oneRails 有很多,属于一个
【发布时间】:2011-09-26 00:49:41
【问题描述】:

我有一个User 模型,它有很多projects 和一个Project 模型,它可以有很多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 当然会返回与用户关联的所有项目。

假设这种关联相当很常见,那么实现我想要的最佳方式是什么?非常感谢任何方向。

【问题讨论】:

    标签: ruby-on-rails associations has-many has-many-through belongs-to


    【解决方案1】:

    为您的项目表添加一个 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

    【讨论】:

    • 感谢您的回答,但这不是我的问题。它是:我正在努力理解的是分配项目创建者的最佳方式(顺便说一下,它不需要是用户,它可以是创建者或其他描述性的东西,只要它是用户类型)。
    • @Nuby 确定什么?确定我正在努力以自动化的方式将用户/创建者分配给项目吗?是的
    • 除非我误读了@Pavling 的回答(和您的问题),否则他的建议是您与 User 表创建第二个关系,称为“Creator”。然后,您可以调用Project.creatorCreatedProjects 关联中获取关联用户。这将解决(我认为)你的问题。至于如何分配它,你可以在模型中做一个before_create 钩子来把它分配给当前登录的用户,或者其他一些用户(取决于你的项目的逻辑)。
    • @injekt - 是的,抱歉,此代码设置了关系 - 如何分配它们取决于代码的操作。就我个人而言,我会在 ProjectsController 创建操作中设置 @project.creator = current_user (或任何用于获取登录用户的辅助方法)
    • 嗯,这很尴尬。如果您认为在我的控制器的创建操作中这样做是可以的,那么设置创建者很好,我想我正在寻找 Rails 通常提供的不必要的魔法。我做错的一件事是我有has_many :created_projects, :class_name =&gt; "Project", :foreign_key =&gt; :creator_id,但在项目中,我有没有外键的belongs_to :creator, :class_name =&gt; 'User',我想我认为它可以从:creator 参考中解决这个问题。非常感谢大家!
    【解决方案2】:

    我想对设计进行一点改进。我们实际上不需要中间模型,因为它不包含除 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
    

    【讨论】:

    • 真的吗?您不关心用户在给定项目中分配的角色,或者他们的分配日期是什么,或者与该用户参与该特定项目相关的任何其他信息?您将在月底之前将该 HABTM 重构为 HMT ;-)
    • @Pavling 你在说什么用户role?我没有让你明白这一点。是否需要完成项目任务的日期?如果有额外的列,那么has_many through 可能是不错的选择。
    • 在一个项目中,用户可能担任技术主管的角色,而在另一个项目中,她可能是 UI 测试员。您可能不想要这些特定信息(或分配日期)——这只是一个例子;但您需要更多信息,而不仅仅是参与项目。当然,HABTM 类型的关系确实有它们的位置,但真的,这个将是一个 HMT。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-22
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多