0

У меня есть приложение Multitenancy и я устанавливаю текущий договор аренды, как это:Как выполнить фильтры ApplicationController, прежде чем resource_from_invitation_token?

class ApplicationController < ActionController::Base 
    around_filter :scope_current_tenancy 

    def scope_current_tenancy 
    Tenancy.current_id = current_tenancy.id if request.subdomain != 'www' 
    yield 
    ensure 
    Tenancy.current_id = nil 
    end 
end 

Тогда в моей модели пользователя у меня есть default_scope определенный доступ только пользователям в моей аренды:

class Postulant < ActiveRecord::Base 

    default_scope ->{ where("enlistments.tenancy_id = ?", Tenancy.current_id).includes(:enlistments).references(:enlistments) } 

Это работает до сих пор, но теперь, используя devise_invitable и пытаясь принять приглашение, я получаю сообщение Filter chain halted as :resource_from_invitation_token rendered or redirected. Проблема в том, что мой scope_current_tenancy фильтр выполняется после resource_from_invitation_token, поэтому resource не загружается правильно.

class Devise::InvitationsController < DeviseController 

    prepend_before_filter :resource_from_invitation_token, :only => [:edit, :destroy] 

    def resource_from_invitation_token 
    # Here 'resource_class' is my Postulant model, so when I call 
    # 'find_by_invitation_token' applies the defined default_scope 
    # which doesn't word without 'scope_current_tenancy' 
    unless params[:invitation_token] && self.resource = resource_class.find_by_invitation_token(params[:invitation_token], true) 
     set_flash_message(:alert, :invitation_token_invalid) 
     redirect_to after_sign_out_path_for(resource_name) 
    end 
    end 

end 

Так что мой вопрос, есть ли способ запустить :scope_current_tenancy, прежде чем :resource_from_invitation_token?
Я попытался изменить around_filter :scope_current_tenancy на prepend_around_filter :scope_current_tenancy, но мне не повезло. Есть предположения?

ответ

1

Поскольку prepend_before_filter :resource_from_invitation_token приходит после вашего ApplicationController, этот фильтр будет добавлен к передней части цепочки фильтров, даже если вы используете prepend_before_filter для scope_current_tenancy. Одним из вариантов может быть, чтобы попробовать что-то вроде:

skip_around_filter :scope_current_tenancy 
prepend_before_filter :resource_from_invitation_token, :only => [:edit, :destroy] 
prepend_around_filter :scope_current_tenancy 

в вашем Devise :: InvitationsController

Не уверен, если это будет работать, но, кажется, стоит выстрел.

В качестве альтернативы вы можете просто удалить строку 'skip_around_filter', предполагая, что scope_current_tenancy является идемпотентным, что, кажется, так.

+0

Это сработало, но я обеспокоен тем, что должен реализовать это решение для каждого разработчика, создав собственные версии этих контроллеров, по крайней мере, где используется 'prepend_before_filter'. Было бы здорово создать общий способ сделать это –

+0

Возможно, вы сможете сделать что-то более элегантное, особенно если 'skip_before_filter' является необязательным, и в этом случае вы можете просто включить модуль с параметром' prepend_around_filter: scope_current_tenancy' для каждого из Создайте контроллеры в инициализаторе. Но в остальном я думаю, что вам, возможно, придется обрабатывать его таким образом для каждого контроллера, который добавляется к цепочке фильтров. –