我正在使用Rails实现多租户应用。我的方法是不使用postgres内置的多租户功能并添加一列来记录子域。这就是问题所在:)
让我们来看看这个例子
class Organisation < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
belongs_to :organisation
end
我在考虑两种方法:
方法1
仅向subdomain
organisations
列
方法2
为subdomain
和organisations
users
列
所以问题是,我应该在上面两种方法之间采用什么样的方法,还是有一种我没有想到的不同方法?
答案 0 :(得分:1)
我的意见将是第一步,有几个原因
我有一个具有多租户功能的项目,下面是我项目中的设计样本
class Company < ApplicationRecord
has_many :users
# transaction
has_many :transactions
has_many :journals , :through => :transactions
# item
has_many :items
# other has_many ...
end
并且在控制器中,您可以使用预先加载来最小化查询(包括/加入)
@company.includes(:users).scope_filter_here.search(params[:q])
答案 1 :(得分:1)
我们运行一个多租户Rails应用程序,只有少于500个表支持的类,如果我不得不猜测我会说其中大约400个与客户端数据有关。
特定于客户端的属性保存在Client
模型中,但我们将client_id
添加到数据库上具有非空约束的每个客户端表。只有少数人被编入索引,但因为他们通常只能通过父记录访问。
我们不必担心设置客户端ID,因为模型通常会:
class Child
after_initialize do
self.client ||= parent.client
end
end
我们将client_id
添加到许多表中,因为我们有很多代码可以执行:
@books = current_user.client.books
...因此,在这些情况下,我们会直接从Client
与模型建立关联,并对client_id
编制索引。
我们将client_id
添加到所有表中,因为出于操作或不寻常的原因,我们经常希望能够找到客户的所有相关记录...
MarketingText.where(client: Client.snowbooks).group(:type).count
......并且必须通过父记录才不方便。
另外,因为我们决定在所有特定于客户的表上执行此操作,所以我们不必对每个表做出决定。
为了解决您的问题,我要做的是仅将子域添加到Organisation
。但是,我会将organisation_id
列添加到每个包含特定于组织的数据的表中。
如果你有很多客户但是你将会普遍熟悉他们的子域名,那么我会在组织上编写一个允许你使用的元程序方法:
Organisation.some_subdomain
...获取所需的组织,然后直接从组织模型中找到具有关联的子记录(在任何表中)...
Organisation.some_subdomain.users
Organisation.some_subdomain.prices
Organisation.some_subdomain.whatevers