Вопрос
Я использую act_as_list в многопользовательском приложении. Я смоделировал мультиарендность, используя этот Railscast: #388 Multitenancy with Scopes (подписка требуется).
Мне нужно убедиться, что мой around_filter работает, чтобы арендаторы не могли влиять на данные других арендаторов.
Каков наилучший способ применить область действия act_as_list для обеспечения мультиарендности, поскольку act_as_list игнорирует default_scope?
Фон
Основная идея состоит в том, чтобы использовать around_filter в application_controller.rb следующим образом:
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) }
Но act_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, поэтому объявление act_as_list выглядит так:
acts_as_list :scope => 'task_id = #{task_id} AND tenant_id = #{Tenant.current_id}'
Это хорошо работает. Но когда я пробую это с моей моделью отправки и включаю for_date в область act_as_list, я получаю эту ошибку:
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
Как бы я добавил такое явное приведение типов? Или есть лучший способ сделать это?