我正在 Rails 中构建一个 Multi-Tenancy Web 应用程序,需要为我的一些模型对象提供特定于租户的标签。
这是一个虚构的例子来描述我的意思:
我有一个角色模型对象,每个租户应该有不同的标签。
class Role < ActiveRecord::Base
has_and_belongs_to_many :users
validates_presence_of :name
end
在摄影租户中,我需要将可用的角色名称列出为:
- 主持人
- 专家
- 学徒
- 查看者
在新闻租户中,我需要将可用的角色名称列出为:
- 编辑
- 副编辑
- 记者
- 读者
本质上,应用程序内始终有四个级别的权限,但在不同的租户中,每个角色都有不同的名称。因此,在上面的示例中,摄影版主和新闻编辑具有相同的权限,只是标签不同。
我可以使用 has_many :through
关联,但我宁愿避免仅仅为了获得角色标签而连接三个表。
class Tenant < ActiveRecord::Base
has_many :roles, :through => :tenant_roles
end
class TenantRole < ActiveRecord::Base
belongs_to :tenant
belongs_to :role
validates_presence_of :name
end
class Role < ActiveRecord::Base
has_many :tenants, :through => :tenant_roles
end
我还考虑过将角色标签存储在 Redis 中(由于其他原因我已经将其存储在 Redis 中)并使用 current_tenant.id
和 role.id
作为 key 。这应该很快,但这是一个坏主意吗?
class Role < ActiveRecord::Base
@tenant_roles = Redis::Set.new('tenant_roles')
def name(current_tenant)
@tenant_roles["#{current_tenant.id}-#{self.id}"]
end
end
关于实现此目的的最佳方法还有其他想法吗?使用 has_many :though
是最好的方法吗?
谢谢!
最佳答案
我想说最好的选择是使用 i18n,因为这只是一个标签问题。额外的好处是,他们已经准备好让您在时机成熟时进行实际翻译。
您可以像这样设置翻译文件
en:
tenant_roles:
tenant1:
role1: "Moderator"
role2: "Expert"
tenant2:
role1: "Editor"
role2: "Sub-Editor"
然后在助手中像这样访问标签
def tenant_role_label tenant_name role_name
t("tenant_roles.#{tenant_name}.#{role_name}")
end
您当然需要确保tenant_name 和role_name 不会更改。也许使用 slug 来做到这一点,这样它就不会依赖于名称或 ID。
我建议的另一个选择是使用模式,但根据我的经验,它比使用 i18n 更难管理。如果您确实需要通过应用程序更新角色标签,那么您将需要使用架构或其他一些数据库选项
关于ruby-on-rails - Rails Multi-Tenancy 应用程序的动态 ActiveRecord 模型标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18208241/