如何基于连接表为has_many:through关联设置default_scope?

时间:2013-09-09 00:25:55

标签: ruby-on-rails has-many-through default-scope

我的问题

如何为用户创建default_scope,以便仅限那些在has_many的连接表中具有当前租户的tenants_users记录(tenants_users.tenant_id == Tenant.current_id)的用户的可见性:通过关联?? 我认为这最终是一个语法问题,但它可能比这更深。

我在做什么

我正在使用Multitenancy with Scopes(需要订阅)作为指南实施多租户。 Ryan使用default_scope根据客户端的当前租户限制可用行。他基本上将tenant_id列添加到包含特定于租户的数据的所有表中,然后在每个模型中包含default_scope:

default_scope { where(tenant_id: Tenant.current_id) }

[Tenant.current_id(cattr_accessor)在用户登录时设置(Tenant.current_id =用户选择的租户的tenant_id)。]

这对我来说非常有用,除了我想要用户和租户的多对多关系(而不是像Railscast所假设的多用户到一个租户):租户可以拥有多个用户,AND我希望用户可以访问多个租户。因此,我的Users表上没有tenant_id列,而是有一个tenants_users连接表,每行有一个tenant_id和user_id。

我正在寻找的结果的不同描述

如果我启动Rails控制台并设置:

Tenant.current_id = 2

...然后说...

User.all

...我想只查看那些在tenants_users表中有一行的用户,例如tenant_id == Tenant.current_id。

如果我说:

User.unscoped.all

然后我想看到所有用户,无论Tenant.current_id是什么。

代码

tenant.rb

class Tenant < ActiveRecord::Base
  cattr_accessor :current_id
  has_many :users, :through => :tenants_users
  has_many :tenants_users

  def self.current_id=(id)
    Thread.current[:tenant_id] = id
  end

  def self.current_id
    Thread.current[:tenant_id]
  end
end

user.rb

class User < ActiveRecord::Base
  # This was the default_scope before I moved tenant_id to the tenants_users table
  # default_scope { where(tenant_id: Tenant.current_id) }

  # What should it be now?
  default_scope ???

  has_many :tenants_users
  has_many :tenants, :through => :tenants_users
end

tenants_user.rb

class TenantsUser < ActiveRecord::Base
  belongs_to :tenant
  belongs_to :user
end

1 个答案:

答案 0 :(得分:0)

这基本上加入了tenants_users表并将条件放在tenant_id属性上:

default_scope { where(tenants_users: {tenant_id: Tenant.current_id}) }