has_many через создание объединенной таблицы с атрибутами - PullRequest
0 голосов
/ 14 апреля 2020

В моем приложении 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

В консоли я могу создать объединенную таблицу (Roles) с 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>

Название работы равно нулю, и я хочу заполните этот атрибут данными при создании.

Как мне сделать что-то подобное?

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

1 Ответ

0 голосов
/ 14 апреля 2020

Вы создаете экземпляр Company, поэтому вы можете установить атрибуты Company только через create.

person.companies.create создаст экземпляр Company. Присвойте его локальной переменной company и, используя company и person объекты, вы можете найти роль и обновить ее атрибут

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
...