Skip to content

Commit

Permalink
Pass the ar_relation for context to should_require_tenant?
Browse files Browse the repository at this point in the history
This is a backwards compatible addition that allows finer control over when
`ActsAsTenant::Errors::NoTenantSet` is raised in the default scope check.
  • Loading branch information
ikraamg committed Jan 16, 2025
1 parent 6860fc9 commit 3a1c678
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 12 deletions.
11 changes: 5 additions & 6 deletions lib/acts_as_tenant.rb
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,11 @@ def self.with_mutable_tenant(&block)
ActsAsTenant.mutable_tenant!(false)
end

def self.should_require_tenant?
if configuration.require_tenant.respond_to?(:call)
!!configuration.require_tenant.call
else
!!configuration.require_tenant
end
def self.should_require_tenant?(context = nil)
config = configuration.require_tenant
return !!config unless config.respond_to?(:call)

config.arity.zero? ? !!config.call : !!config.call(context)
end
end

Expand Down
12 changes: 6 additions & 6 deletions lib/acts_as_tenant/model_extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def acts_as_tenant(tenant = :account, scope = nil, **options)
belongs_to tenant, scope, **valid_options

default_scope lambda {
if ActsAsTenant.should_require_tenant? && ActsAsTenant.current_tenant.nil? && !ActsAsTenant.unscoped?
if ActsAsTenant.should_require_tenant?(self) && ActsAsTenant.current_tenant.nil? && !ActsAsTenant.unscoped?
raise ActsAsTenant::Errors::NoTenantSet
end

Expand Down Expand Up @@ -46,10 +46,10 @@ def acts_as_tenant(tenant = :account, scope = nil, **options)
before_validation proc { |m|
if ActsAsTenant.current_tenant
if options[:polymorphic]
m.send("#{fkey}=".to_sym, ActsAsTenant.current_tenant.class.to_s) if m.send(fkey.to_s).nil?
m.send("#{polymorphic_type}=".to_sym, ActsAsTenant.current_tenant.class.to_s) if m.send(polymorphic_type.to_s).nil?
m.send(:"#{fkey}=", ActsAsTenant.current_tenant.class.to_s) if m.send(fkey.to_s).nil?
m.send(:"#{polymorphic_type}=", ActsAsTenant.current_tenant.class.to_s) if m.send(polymorphic_type.to_s).nil?
else
m.send "#{fkey}=".to_sym, ActsAsTenant.current_tenant.send(pkey)
m.send :"#{fkey}=", ActsAsTenant.current_tenant.send(pkey)
end
end
}, on: :create
Expand Down Expand Up @@ -80,13 +80,13 @@ def acts_as_tenant(tenant = :account, scope = nil, **options)
# - Add an override to prevent unnecessary db hits
# - Add a helper method to verify if a model has been scoped by AaT
to_include = Module.new {
define_method "#{fkey}=" do |integer|
define_method :"#{fkey}=" do |integer|
write_attribute(fkey.to_s, integer)
raise ActsAsTenant::Errors::TenantIsImmutable if !ActsAsTenant.mutable_tenant? && tenant_modified?
integer
end

define_method "#{ActsAsTenant.tenant_klass}=" do |model|
define_method :"#{ActsAsTenant.tenant_klass}=" do |model|
super(model)
raise ActsAsTenant::Errors::TenantIsImmutable if !ActsAsTenant.mutable_tenant? && tenant_modified?
model
Expand Down
15 changes: 15 additions & 0 deletions spec/acts_as_tenant/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@
expect(ActsAsTenant.should_require_tenant?).to eq(false)
end

it "evaluates lambda with context" do
account = accounts(:foo)
test_context = nil

ActsAsTenant.configure do |config|
config.require_tenant = ->(context) {
test_context = context
context.klass.name == "Project"
}
end

expect { account.projects.create!(name: "foobar") }.to raise_error(ActsAsTenant::Errors::NoTenantSet)
expect(test_context.klass.name).to eq("Project")
end

it "evaluates boolean" do
ActsAsTenant.configure do |config|
config.require_tenant = true
Expand Down

0 comments on commit 3a1c678

Please sign in to comment.