У меня очень особые случаи.Я понимаю, что дизайн БД не очень хорош, но я не могу это изменить.
class Employer < ApplicationRecord
has_many :contract_employers
has_many :contracts, through: :contract_employers
has_many :crm_contacts, through: :contract_employers
# typical join table, with key: contract_id and employer_id
class ContractEmployer < ApplicationRecord
belongs_to :contract
belongs_to :employer
has_many :crm_contacts
# CrmContact table has key: contract_employer_id
class CrmContact < ApplicationRecord
belongs_to :contract_employer
has_one :employer, through: :contract_employer
Учитывая
employer = Employer.create
У меня нет проблем с запуском
employer.contracts.create
Однако, если я попытаюсь запустить
employer.crm_contacts.create
Это вызовет ошибку
ActiveRecord :: HasManyThroughCantAssociateThroughHasOneOrManyReflection: Невозможно изменить ассоциацию «Employer # crm_contacts», поскольку исходный класс отражения «CrmContact»связан с 'ContractEmployer' через: has_many.
Я проверил исходный код рельсов, в основном он очень четко говорит
# Construct attributes for :through pointing to owner and associate. This is used by the
# methods which create and delete records on the association.
#
# We only support indirectly modifying through associations which have a belongs_to source.
# This is the "has_many :tags, through: :taggings" situation, where the join model
# typically has a belongs_to on both side. In other words, associations which could also
# be represented as has_and_belongs_to_many associations.
#
# We do not support creating/deleting records on the association where the source has
# some other type, because this opens up a whole can of worms, and in basically any
# situation it is more natural for the user to just create or modify their join records
# directly as required.
Так что только типичная таблица соединенияподдерживает model.associations.create
?Любое предложение для моего пользовательского случая?
Возьмите, к примеру, мой случай, даже рельс готов выполнить эту работу.Как employer.crm_contacts.create
создать запись в средней таблице ContractEmployer
?Да, он знает employer.id
, но не имеет понятия, что такое contract.id
, верно?