在 Rails 中管理多个品牌:RobinReach 的多租户模式
Source: Dev.to

挑战:多品牌管理
想象一下,一个用户在你的平台上管理三家公司。每家公司都有:
- 各自的社交媒体账号
- 已排程的帖子
- 团队成员和角色
- 分析与绩效数据
如果没有适当的隔离,跨租户的数据泄露将成为噩梦。多租户不仅是一种数据库模式,更是应用每一层的思维方式。
基于工作区的多租户
在 RobinReach,我们将每个品牌或工作区建模为一个租户。所有核心模型——Post、SocialProfile、Member——都限定在租户范围内。我们使用线程安全的 Current 对象来保存租户上下文:
# app/models/current.rb
class Current < ActiveSupport::CurrentAttributes
attribute :company
end
这让每个模型都能轻松引用当前租户:
# app/models/post.rb
class Post < ApplicationRecord
belongs_to :company
default_scope { where(company_id: Current.company.id) }
end
有了这个模式,每一次查询都会自动遵守租户边界。
无缝的工作区切换
用户期望在工作区之间切换而无需重新登录。我们将当前工作区存放在会话中:
def switch_workspace(company_id)
session[:current_company_id] = company_id
Current.company = Company.find(company_id)
end
现在,查看帖子、排程内容或管理成员等操作始终限定在所选工作区。
多租户环境中的后台任务
多租户不仅局限于数据库查询,后台任务也必须遵守租户边界。
经验教训
- 始终将租户 ID 传递给后台任务。
- 使任务具备幂等性,以防止跨租户的副作用。
- 有策略地使用 Sidekiq 队列;高流量租户可能需要独立的队列。
工作区多租户的最佳实践
- 在所有层面——模型、服务、任务和控制器——强制租户隔离。
- 使用线程安全的上下文对象(
Current)来存放租户信息。 - 为快速工作区切换设计 UI。
- 保持后台任务幂等且了解租户。
- 在适当情况下对每个租户进行缓存,以降低数据库负载。
- 监控每个工作区的性能,及早发现高负载租户。
结论
在 Rails 中构建多品牌 SaaS 不仅是技术挑战,更是一种设计思维。RobinReach 通过细致的作用域控制、后台任务设计和工作区隔离,展示了如何交付流畅的多租户体验。
对于构建 SaaS 平台的 Rails 开发者来说,这些模式可以帮助你避免未来的头疼,并为应用的扩展奠定基础。