has_many通过创建具有属性的联合表

时间:2020-04-14 10:22:53

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-4 ruby-on-rails-6

在我的Rails应用中,有3种模型:

class Person < ApplicationRecord
  has_many :roles
  has_many :companies, through: :roles
end

class Company < ApplicationRecord
  has_many :roles
  has_many :people, through: :roles
end

class Role < ApplicationRecord
  belongs_to :person
  belongs_to :company
end

在控制台中,我可以使用person_id和company_id创建一个联合表(角色),但是我也有job_title字段,我想在创建过程中传递值。

这就是我创建联合表的方式:

person = Person.find(id)
person.companies.create(legal_name: "Company name Ltd.")

结果我得到:

#<Role id: 1, person_id: 2, company_id: 25, job_title: nil>

职位标题为nil,我想在创建期间用数据填充此属性。

我该怎么做?

person = Person.find(id)
person.companies.create(legal_name: "Company name Ltd.", roles: [job_title: "Job title"])

1 个答案:

答案 0 :(得分:0)

您正在创建Company的实例,因此只能通过Company设置create的属性。

person.companies.create将创建Company的实例。将其分配给局部变量company,并使用companyperson对象可以找到角色并更新其属性

ActiveRecord::Base.transaction.do
  person = Person.find(id)
  person.companies.create!(legal_name: "Company name Ltd.")

  role = person.roles.find_by!(person: person, company: company
  role.update!(job_title: 'Manager')
end

使用带有爆炸!版本方法的事务将确保记录的完整性。

编辑

如果对联接模型上的属性进行验证怎么办?

不保存公司记录,而只是保存build并在创建角色时使用新实例。

ActiveRecord::Base.transaction.do
  person = Person.find(id)
  company = person.companies.build(legal_name: "Company name Ltd.")
  person.roles.create!(job_title: 'Manager', company: company)
end