【问题标题】:create a model instance with associations创建具有关联的模型实例
【发布时间】:2014-08-06 10:03:05
【问题描述】:

我正在开发一个 Rails 应用程序。 我遇到了 Rails 关联的问题: 我有 3 个模型:User、Company 和 CompanyMember

#  id :integer not null, primary key
class User < ActiveRecord::Base
  has_one :company_member
  has_one :company, through: :company_member
end

#  id          :integer          not null, primary key
#  name        :string(255)      not null
class Company < ActiveRecord::Base
  has_many :company_members
  has_many :members, through: :company_members, foreign_key: "user_id", source: :user
  has_many :admins, -> {where admin: true }, through: :company_members, foreign_key: "user_id", source: :user
end

#  id         :integer          not null, primary key
#  company_id :integer
#  user_id    :integer
#  admin      :boolean
#  created_at :datetime
#  updated_at :datetime
class CompanyMember < ActiveRecord::Base
  belongs_to :company
  belongs_to :user
end

一个用户只能拥有一家公司。他可以是这家公司的管理员。一家公司可以有多个管理员。

所以当我想向公司添加成员时,我会这样做:company.members

现在我想添加一个用户作为管理员:我要做的是:company.admins

有可能通过 Rails 关联吗?因为实际上,它不起作用:/:company_member 记录为 {user_id: 5, company_id: 8, admin: false} 你能帮帮我吗?

谢谢!

我正在使用 Rails 4.1.3 和 ruby​​ 2.1.2

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 associations


    【解决方案1】:

    当您在has_many 关系中指定范围时,您只能自定义 has_many 使用的查询。因此,如果您将用户添加到公司的管理员列表中,它不会使其成为管理员。

    您可以通过设置关联回调来实现此目的。 Rails 将要添加或删除的对象传递给回调,您可以将其设置为管理员。

    class Company < ActiveRecord::Base
      has_many :company_members
      has_many :members, through: :company_members, foreign_key: "user_id", source: :user
      has_many :admins, -> {where admin: true }, through: :company_members, foreign_key: "user_id", source: :user, after_add: :set_user_as_admin
    
      def set_user_as_admin(user)
        user.company_member.update(admin: true)
      end
    end
    

    【讨论】:

    • 感谢您的支持。我尝试了您的解决方案,但它尝试在模型 User 上设置 admin: true 而不是在模型 CompanyMember 上。
    • 哦,对了。我认为管理字段在用户模型上。由于每个用户都有一个 company_member,您可以通过关联将该成员设置为管理员。答案已更新。
    【解决方案2】:

    我想如果有人感兴趣怎么办:

    在公司中,协会管理员必须是这样的:

    class Company < ActiveRecord::Base
      has_many :company_members
      has_many :members, through: :company_members, source: :user
      has_many :admins, -> {where(company_members: {admin: true })}, through: :company_members, source: :user
    end
    

    现在我有了预期的行为

    company.admins << user
    

    它使用 admin: true (默认为 false)添加一个 company_member 实例

    所以我不需要 SampritiPanda 建议的回调,但谢谢老兄!

    【讨论】:

      猜你喜欢
      • 2014-07-10
      • 2017-06-13
      • 2020-10-11
      • 2016-04-02
      • 1970-01-01
      • 1970-01-01
      • 2010-11-13
      • 2023-04-07
      • 1970-01-01
      相关资源
      最近更新 更多