0

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?

Winston Kotzan
  • 1,979
  • 20
  • 25
  • post the relevant model code and you might want to read this if you haven't already http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html – Dan Rubio Oct 20 '17 at 20:55

1 Answers1

0

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
Winston Kotzan
  • 1,979
  • 20
  • 25