ruby-on-railsrubyassociationsmodel-associationsacts-as-tenant

How to build associated records before "tenant" class is saved with acts_as_tenant gem?


Example...

I have a class called client which is my tenant model.
I have associated records to save along with each new client that gets created. Let's call them tasks.
I created an after_initialize callback inside of client that calls a method called build_defaults which does the following...

def build_defaults
self.tasks.build(
  Task.new({
    :name => 'task 1',
    :description => 'task 1 desc',
    :view_module => 'task_1_template'
  }),
  Task.new({
    :name => 'task 2',
    :description => 'task 2 desc',
    :view_module => 'task_2_template'
  }),
  Task.new({
    :name => 'task 3',
    :description => 'task 3 desc',
    :view_module => 'task_3_template'
  }),
  Task.new({
    :name => 'task 4',
    :description => 'task 4 desc',
    :view_module => 'task_4_template'
  }),
  Task.new({
    :name => 'task 5',
    :description => 'task 5 desc',
    :view_module => 'task_5_template'
  })
)
end

The task class is setup as acts_as_tenant :client

When I go to do @client = new Client( :name => "Test Client" ) It raises ActsAsTenant::Errors::NoTenantSet: ActsAsTenant::Errors::NoTenantSet

Is there a way to conditionally bypass acts_as_tenant's check when it's a new_record? or a better way to handle this type of thing?

I'm fairly new to rails / ruby as of a few months ago...?

UPDATE

Well, I figured out if I change it to an "after_create" and set ActsAsTenant.current_tenant = self within the method I can do self.tasks.create! calls... but not sure if overriding ActsAsTenant.current_tenant is a good idea?

  after_create :build_defaults
  def build_defaults
    ActsAsTenant.current_tenant = self
    self.tasks.create!({
      :name => 'Facebook > Page Like',
      :description => 'Request that they like your page.',
      :view_module => 'facebook_page_like'
    })
    self.tasks.create!({
      :name => 'Facebook > Share',
      :description => 'Share a link on Facebook',
      :view_module => 'facebook_share_link'
    })
    self.tasks.create!({
      :name => 'Twitter > Tweet',
      :description => 'Post a tweet on a user behalf.',
      :view_module => 'twitter_tweet'
    })
    self.tasks.create!({
      :name => 'Twitter > Follow',
      :description => 'Follow the company twitter user.',
      :view_module => 'twitter_follow'
    })
    self.tasks.create!({
      :name => 'Giveaway Share',
      :description => 'This allows you to earn 5 extra entries by re-sharing this giveaway.',
      :view_module => 'giveaway_share'
    })
  end

Solution

  • If you create a new tenant and then want to create a number of records associated with the new client, you will first need to set the current tenant or acts_as_tenant will not allow you to do so.

    Your approach works, but acts_as_tenant has a specific API for this as well (also check the read me):

    Setting the current tenant for a block

    ActsAsTenant.with_tenant(newly_created_tenant) do
      # Current tenant is set for all code in this block
    end
    

    This works.

    However, if you want to give the new tenant direct access to his app after creating his account. You would be better of logging him in and then creating the defaults. How to log him in is dependent on your authentication solution.