【问题标题】:How do I set a default_scope for a has_many :through association based on the join table?如何为 has_many 设置 default_scope :通过基于连接表的关联?
【发布时间】:2013-09-09 00:25:54
【问题描述】:

我的问题

我如何为用户创建一个 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 (a cattr_accessor) 在用户登录时设置(Tenant.current_id = 用户选择的租户的tenant_id)。]

这对我很有用,除了我想要用户和租户的多对多关系(而不是 Railscast 假设的多用户对一租户):一个租户可以有多个用户,并且我希望用户可以访问多个租户。因此,我的 Users 表上没有一个 tenant_id 列,而是有一个 tenant_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

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 这就是我最终做的事情:default_scope { where('users.id IN (?)', TenantsUser.where(:tenant_id =&gt; Tenant.current_id).pluck(:user_id)) } 您的解决方案看起来 更干净,但我需要对其进行测试,看看它是否能按我的需要工作。我认为你的基本上做同样的事情,只是更好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-07
    相关资源
    最近更新 更多