Question

I have these models in my multi-tenant app:

class Tenant < ActiveRecord::Base
  has_many :userroles
  has_many :users, through: :userroles
  has_many :roles, through: :userroles
  has_many :admins, -> { joins(:roles).where("roles.name = 'admin'").uniq }, through: :userroles, class_name: 'User', source: :user
end

class Role < ActiveRecord::Base
  has_paper_trail
  acts_as_paranoid
  has_many :userroles, :dependent => :destroy
  has_many :users, :through => :userroles
end

class Userrole < ActiveRecord::Base
  acts_as_tenant(:tenant)
  has_paper_trail
  belongs_to :user
  belongs_to :role
end

I use gem ActsAsTenant written by Erwin (source code at github). When current_tenant doesn't set my code work right, but if I set current_tenant, I got errors. In console I got those errors:

2.1.0 :001 > ActsAsTenant.current_tenant
 => nil 
2.1.0 :002 > t = Tenant.first
2.1.0 :004 > t.admins.count
   (1.5ms)  SELECT DISTINCT COUNT(DISTINCT "users"."id") FROM "users" INNER JOIN "userroles" "userroles_users_join" ON "userroles_users_join"."user_id" = "users"."id" INNER JOIN "roles" ON "roles"."id" = "userroles_users_join"."role_id" AND "roles"."deleted_at" IS NULL INNER JOIN "userroles" ON "users"."id" = "userroles"."user_id" WHERE "users"."deleted_at" IS NULL AND "userroles"."tenant_id" = $1 AND (roles.name = 'admin')  [["tenant_id", 1]]
 => 1 
2.1.0 :005 > ActsAsTenant.current_tenant = t
2.1.0 :006 > t.admins.count
   (2.6ms)  SELECT DISTINCT COUNT(DISTINCT "users"."id") FROM "users" INNER JOIN "userroles" "userroles_users_join" ON "userroles_users_join"."user_id" = "users"."id" AND (userroles.tenant_id = 1) INNER JOIN "roles" ON "roles"."id" = "userroles_users_join"."role_id" AND "roles"."deleted_at" IS NULL INNER JOIN "userroles" ON "users"."id" = "userroles"."user_id" WHERE "users"."deleted_at" IS NULL AND "userroles"."tenant_id" = $1 AND (userroles.tenant_id = 1) AND (roles.name = 'admin')  [["tenant_id", 1]]
PG::UndefinedTable: ERROR:  invalid reference to FROM-clause entry for table "userroles"
LINE 1: ...erroles_users_join"."user_id" = "users"."id" AND (userroles....
                                                             ^
HINT:  Perhaps you meant to reference the table alias "userroles_users_join".
: SELECT DISTINCT COUNT(DISTINCT "users"."id") FROM "users" INNER JOIN "userroles" "userroles_users_join" ON "userroles_users_join"."user_id" = "users"."id" AND (userroles.tenant_id = 1) INNER JOIN "roles" ON "roles"."id" = "userroles_users_join"."role_id" AND "roles"."deleted_at" IS NULL INNER JOIN "userroles" ON "users"."id" = "userroles"."user_id" WHERE "users"."deleted_at" IS NULL AND "userroles"."tenant_id" = $1 AND (userroles.tenant_id = 1) AND (roles.name = 'admin')
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  invalid reference to FROM-clause entry for table "userroles"

Problem is when I set current_tenant. All works right before setting it. What could be the problem? In gem's code I can't find anything strange.

Was it helpful?

Solution

I change has_many condition:

has_many :admins, -> { for_tenanted_roles.where("roles.name = 'admin'").uniq }, through: :userroles, class_name: 'User', source: :user

And in user.rb

scope :for_tenanted_roles, -> { joins('INNER JOIN "roles" ON "roles"."id" = "userroles"."role_id" AND "roles"."deleted_at" IS NULL') }

It's just handy overrided joins(:roles)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top