ActsAsTenant с вложенными вложенными атрибутами вызывает ActsAsTenant::Errors::NoTenantSet: ActsAsTenant::Errors::NoTenantSet

Я работаю над страницей администратора для приложения с моделью DealerBranch и арендованной ассоциацией под названием Address. У меня есть контроллер, который выглядит так для создания новой ветки дилера:

class Admin::DealerBranchesController < Admin::AdminApplicationController
  def create
    @dealer_branch = DealerBranch.new(dealer_branch_attributes)
    if @dealer_branch.save
      render :success
    else
      render :new
    end
  end
end

При запуске create он включает в себя все атрибуты, необходимые для создания связанного адреса. Однако клиент для адреса еще не создан, потому что мы строим как клиента (DealerBranch), так и связанного с ним клиента (Address). В строке с назначением @dealer_branch я получаю ошибку ActsAsTenant::Errors::NoTenantSet: ActsAsTenant::Errors::NoTenantSet

Как правильно обращаться с такими вложенными атрибутами?

1 ответ

Решение

Это закончилось тем, что стало проблемой с курицей и яйцом. Невозможно создать адрес, потому что ему нужен DealerBranch, к которому должен принадлежать адрес. Родительский объект DealerBranch еще не сохранен. Для того, чтобы вложение работало, я создал create_with_address метод, который разбивает его, чтобы сначала сохранить DealerBranch:

  # We need this method to help create a DealerBranch with nested Address because address needs DealerBranch
  # to exist to satisfy ActsAsTenant
  def self.create_with_address(attributes)
    address_attributes = attributes.delete(:address_attributes)
    dealer_branch = DealerBranch.new(attributes)

    begin
      ActiveRecord::Base.transaction do
        dealer_branch.save!
        ActsAsTenant.with_tenant(dealer_branch) do
          dealer_branch.create_address!(address_attributes)
        end
      end
    rescue StandardError => e
      if dealer_branch.address.nil?
        # rebuild the attributes for display of form in case they were corrupted and became nil
        ActsAsTenant.with_tenant(dealer_branch) { dealer_branch.build_address(address_attributes) }
      end

      unless dealer_branch.valid? && dealer_branch.address.valid?
        return dealer_branch
      else
        raise e
      end
    end

    dealer_branch.reload
  end
Другие вопросы по тегам