I'm working on the admin page for an application with a model called DealerBranch and a tenanted nested association called Address. I have a controller that looks like this for creating a new dealer branch:
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
When create runs it includes all of the attributes necessary to create the associated Address. However, the tenant for address is not yet created because we're building both the tenant (DealerBranch) and the associated tenanted (Address). On the line with the assignment to @dealer_branch I get the error ActsAsTenant::Errors::NoTenantSet: ActsAsTenant::Errors::NoTenantSet
What's the proper way of handling nested attributes like this?
This ended up being sort of a chicken and egg problem. Can't create the Address yet because it needs a DealerBranch, which Address needs to be belong to. The parent object DealerBranch has not been saved yet. In order for the nesting to work I created a create_with_address
method which breaks it down to save the DealerBranch first:
# 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