Skip to content

Run controller filter to activate_draper as early as possible #721

@bf4

Description

@bf4

Fixes #640

I haven't figured out how to fix this deterministically in the Draper code, yet, but here's a breakdown of the issue and the fix, so hopefully someone can make a PR.

This is on Draper 2.1.0, Rails 4.2.5.1, Ruby 2.2.

  1. When going to /users/sign_in we were getting
    a NoMethodError undefined method 'host' for nil:NilClass
  2. This is because the h.request was returning nil
  3. This is because the view context proxy controller is set in a way
    that mocks the controller and request when
    Draper::ViewContext.controller is nil. Draper::ViewContext.controller || ApplicationController.new. https://github.com/drapergem/draper/blob/v2.1.0/lib/draper/view_context/build_strategy.rb#L39-L42
  4. Draper::ViewContext.controller is set in the controller by the
    callback before_filter :activate_draper https://github.com/drapergem/draper/blob/v2.1.0/lib/draper.rb#L36
  5. That means, that any before_action filters that 1) use draper and
    2) run before the active_draper callback won't have the controller
    context set

The specific callbacks we had running was Devise::SessionController#after_sign_in_path_for and the code fix was:

def after_sign_in_path_for(user)
+    # Draper before filter to set controller context hasn't run yet
+    activate_draper
  user.decorate.sign_in_path
end

where the UserDecorator#sign_in_path was calling h.rails_admin.dashboard_path.

I tried futzing with changing the Draper filter to prepend_before_action :activate_draper, but that didn't work, so I went with the fix above and made this issue :)

It's possible we may want to modify the initializer to run earlier via :after => 'action_controller.set_configs' as below, but I haven't tried it.

  initializer "draper.setup_action_controller", :after => 'action_controller.set_configs' do |app|
      ActiveSupport.on_load :action_controller do
        Draper.setup_action_controller self
      end
    end

    initializer "draper.setup_action_mailer", :after => 'action_controller.set_configs' do |app|
      ActiveSupport.on_load :action_mailer do
        Draper.setup_action_mailer self
      end
    end

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions