问题
我在多租户应用程序中使用acts_as_list。我使用这个 Railscast 对多租户建模:#388 Multitenancy with Scopes(需要订阅)。
我需要确保我的 around_filter 正常工作,以便租户不会影响其他租户的数据。
由于acts_as_list 忽略default_scope,确定acts_as_list 范围以强制执行多租户的最佳方法是什么?
背景
基本思想是在 application_controller.rb 中使用 around_filter,如下所示:
class ApplicationController < ActionController::Base
include SessionsHelper
around_filter :update_current_tenant
#current_tenant is defined in sessions_helper.rb, included above
def update_current_tenant
Tenant.current_id = current_tenant.id if current_tenant
end
end
这样,每次在应用程序中加载页面时,都会设置 current_tenant,我可以使用 default_scope 来限制仅访问 current_tenant 的内容。像这样:
default_scope { where(tenant_id: Tenant.current_id) }
但是acts_as_list 使用Model.unscoped(在本例中为Submission.unscoped),绕过了我的default_scope。
这是我正在研究的特定模型:
class Submission < ActiveRecord::Base
default_scope { where(tenant_id: Tenant.current_id) }
acts_as_list scope: [:for_date, :tenant_id] # Works, but is this safe?
# The one below is closer to what I want, but it bombs
#acts_as_list :scope => 'for_date = #{for_date} AND tenant_id = #{Tenant.current_id}'
end
我在其他几个地方这样做,但我使用 id 列而不是 for_date,所以acts_as_list 声明如下所示:
acts_as_list :scope => 'task_id = #{task_id} AND tenant_id = #{Tenant.current_id}'
效果很好。但是当我用我的提交模型尝试这个,并在acts_as_list范围中包含for_date时,我得到了这个错误:
PG::UndefinedFunction: ERROR: operator does not exist: date = integer
LINE 1: ... (submissions.position IS NOT NULL) AND (for_date = 2013-11-...
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
: SELECT "submissions".* FROM "submissions" WHERE (submissions.position IS NOT NULL) AND (for_date = 2013-11-25 AND tenant_id = 1) ORDER BY submissions.position DESC LIMIT 1
我将如何添加这样一个明确的类型转换?还是有更好的方法来做到这一点?