Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Readme instructions for setting a default tenant when using rails console do not correctly handle reload! #344

Open
sebastianiorga opened this issue Nov 13, 2024 · 0 comments

Comments

@sebastianiorga
Copy link

Versions

acts_as_tenant (1.0.1)
rails (7.2.1.2)

Problem

I am using acts_as_tenant with an Account model for the tenant. I've got an acts_as_tenant.rb initializer containing

SET_TENANT_PROC = lambda do
  if defined?(Rails::Console)
    puts "> ActsAsTenant.current_tenant = Account.find_by!(name: 'Demo')"

    ActsAsTenant.current_tenant = Account.find_by!(name: 'Demo')
  end
end

ActsAsTenant.configure do |config|
  config.require_tenant = lambda do
    ....
  end

  # Customize the query for loading the tenant in background jobs
  config.job_scope = -> { all }
end

Rails.application.configure do
  if Rails.env.development?
    # Set the tenant to the first account in development on load
    config.after_initialize do
      SET_TENANT_PROC.call
    end

    # Reset the tenant after calling 'reload!' in the console
    ActiveSupport::Reloader.to_complete do
      SET_TENANT_PROC.call
    end
  end
end

I think this matches the instructions in the Readme https://github.com/ErwinM/acts_as_tenant?tab=readme-ov-file#configuration-options

This works on initial console load, however after I run reload! in the console ActsAsTenant.current_tenant ends up being nil.

> ActsAsTenant.current_tenant = Account.find_by!(name: 'Demo')
Loading development environment (Rails 7.2.1.2)
[1] pry(main)> ActsAsTenant.current_tenant
=> #<Account:0x000070e6a3de76a0 id: 3, account_url_segment: "demo", name: "Demo", created_at: "2024-11-13 11:37:32.973746000 +0000", updated_at: "2024-11-13 11:37:32.973746000 +0000">
[2] pry(main)> reload!
Reloading...
> ActsAsTenant.current_tenant = Account.find_by!(name: 'Demo')
  Account Load (0.1ms)  SELECT "accounts".* FROM "accounts" WHERE "accounts"."name" = $1 LIMIT $2  [["name", "Demo"], ["LIMIT", 1]]
=> true
[3] pry(main)> ActsAsTenant.current_tenant
=> nil

If I change the proc to

SET_TENANT_PROC = lambda do
  if defined?(Rails::Console)
    puts "> ActsAsTenant.current_tenant = Account.find_by!(name: 'Demo')"

    ActsAsTenant.current_tenant = Account.find_by!(name: 'Demo')
   
    ActsAsTenant::Current.after_reset do
      next if ActsAsTenant.current_tenant.present?

      puts "> ActsAsTenant.current_tenant = Account.find_by!(name: 'Demo')"
      ActsAsTenant.current_tenant = Account.find_by!(name: 'Demo')
    end
  end
end

Then it seems to work correctly after reload! as well

[1] pry(main)> ActsAsTenant.current_tenant
=> #<Account:0x00007d9ea2c99dc0 id: 3, account_url_segment: "demo", name: "Demo", created_at: "2024-11-13 11:37:32.973746000 +0000", updated_at: "2024-11-13 11:37:32.973746000 +0000">
[2] pry(main)> reload!
Reloading...
> ActsAsTenant.current_tenant = Account.find_by!(name: 'Demo')
  Account Load (0.3ms)  SELECT "accounts".* FROM "accounts" WHERE "accounts"."name" = $1 LIMIT $2  [["name", "Demo"], ["LIMIT", 1]]
> ActsAsTenant.current_tenant = Account.find_by!(name: 'Demo')
  Account Load (0.1ms)  SELECT "accounts".* FROM "accounts" WHERE "accounts"."name" = $1 LIMIT $2  [["name", "Demo"], ["LIMIT", 1]]
> ActsAsTenant.current_tenant = Account.find_by!(name: 'Demo')
  CACHE Account Load (0.0ms)  SELECT "accounts".* FROM "accounts" WHERE "accounts"."name" = $1 LIMIT $2  [["name", "Demo"], ["LIMIT", 1]]
> ActsAsTenant.current_tenant = Account.find_by!(name: 'Demo')
  CACHE Account Load (0.0ms)  SELECT "accounts".* FROM "accounts" WHERE "accounts"."name" = $1 LIMIT $2  [["name", "Demo"], ["LIMIT", 1]]
=> true
[3] pry(main)> ActsAsTenant.current_tenant
=> #<Account:0x00007d9ea32ddd58 id: 3, account_url_segment: "demo", name: "Demo", created_at: "2024-11-13 11:37:32.973746000 +0000", updated_at: "2024-11-13 11:37:32.973746000 +0000">
[4] pry(main)> 

Diagnostic

It seems based on the log output that ActsAsTenant::Current is getting reset repeatedly during a reload!? The workaround seems fine to me, but maybe it indicates some problem in the gem, maybe worth updating the Readme at least.

I also tried to remove the to_complete block from the initializer, since I thought just configuring after_reset on console load would be enough, but it didn't work(maybe the class gets reset somehow and clears callbacks, not sure how CurrentAttributes works internally).

I did print ActsAsTenant.object_id and ActsAsTenant::Current.object_id and those do not change between reload!s so I don't think this is an issue of the constants themselves getting swapped out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant