Skip to content

Commit

Permalink
Add support for acts_as_tenant :through (#275)
Browse files Browse the repository at this point in the history
* Add support for acts_as_tenant :through. This allows you to use acts_as_tenant for has-and-belongs-to-many relationships.

* Update readme to include  option.
  • Loading branch information
scarhand authored Feb 23, 2022
1 parent a6c5d37 commit a05d9a2
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 3 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,28 @@ You can also explicitly specifiy a primary_key for AaT to use should the key dif
acts_as_tenant(:account, :primary_key => 'primaryID') # by default AaT expects id
```


### Has and belongs to many ###

You can scope a model that is part of a HABTM relationship by using the `through` option.

```ruby
class Organisation < ActiveRecord::Base
has_many :organisations_users
has_many :users, through: :organisations_users
end

class User < ActiveRecord::Base
has_many :organisations_users
acts_as_tenant :organisation, through: :organisations_users
end

class OrganisationsUser < ActiveRecord::Base
belongs_to :user
acts_as_tenant :organisation
end
```

Configuration options
---------------------
An initializer can be created to control (currently one) option in ActsAsTenant. Defaults
Expand Down
12 changes: 9 additions & 3 deletions lib/acts_as_tenant/model_extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,15 @@ def acts_as_tenant(tenant = :account, **options)
keys = [ActsAsTenant.current_tenant.send(pkey)].compact
keys.push(nil) if options[:has_global_records]

query_criteria = {fkey.to_sym => keys}
query_criteria[polymorphic_type.to_sym] = ActsAsTenant.current_tenant.class.to_s if options[:polymorphic]
where(query_criteria)
if options[:through]
query_criteria = {options[:through] => {fkey.to_sym => keys}}
query_criteria[polymorphic_type.to_sym] = ActsAsTenant.current_tenant.class.to_s if options[:polymorphic]
joins(options[:through]).where(query_criteria)
else
query_criteria = {fkey.to_sym => keys}
query_criteria[polymorphic_type.to_sym] = ActsAsTenant.current_tenant.class.to_s if options[:polymorphic]
where(query_criteria)
end
else
all
end
Expand Down
2 changes: 2 additions & 0 deletions spec/dummy/app/models/account.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class Account < ActiveRecord::Base
has_many :projects
has_many :global_projects
has_many :users_accounts
has_many :users, through: :users_accounts
end
6 changes: 6 additions & 0 deletions spec/dummy/app/models/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class User < ActiveRecord::Base
has_many :users_accounts
has_many :accounts, through: :users_accounts

acts_as_tenant :account, through: :users_accounts
end
4 changes: 4 additions & 0 deletions spec/dummy/app/models/users_account.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class UsersAccount < ActiveRecord::Base
acts_as_tenant :account
belongs_to :user
end
10 changes: 10 additions & 0 deletions spec/dummy/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,14 @@
t.column :polymorphic_tenant_commentable_type, :string
t.column :account_id, :integer
end

create_table :users, force: true do |t|
t.column :name, :string
end

create_table :users_accounts, force: true do |t|
t.column :user_id, :integer
t.column :account_id, :integer
t.index [:user_id, :account_id], name: :index_users_accounts_on_user_id_and_account_id, unique: true
end
end
8 changes: 8 additions & 0 deletions spec/fixtures/accounts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,11 @@ with_domain:
name: domain
subdomain: domain
domain: domain.com

abc:
name: abc
users: john, bob # habtm relation

def:
name: def
users: john, alice # habtm relation
8 changes: 8 additions & 0 deletions spec/fixtures/users.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
john:
name: john

bob:
name: bob

alice:
name: alice
19 changes: 19 additions & 0 deletions spec/models/model_extensions_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,25 @@
end
end

describe "acts_as_tenant :through" do
let(:account) { accounts(:abc) }

it "should scope User.all to the current tenant if set" do
ActsAsTenant.current_tenant = account
expect(User.count).to eq(account.users.count)
expect(User.all).to eq(account.users)
end

it "should return all users when no current tenant is set" do
expect(User.count).to eq(3)
end

it "should allow unscoping" do
ActsAsTenant.current_tenant = account
expect(User.unscoped.count).to be > account.users.count
end
end

describe "A tenant model with global records" do
before do
ActsAsTenant.current_tenant = account
Expand Down

0 comments on commit a05d9a2

Please sign in to comment.