ruby-grape / grape-swagger-rails

Swagger UI as Rails Engine for grape-swagger gem.
MIT License
251 stars 197 forks source link

GrapeSwaggerRails::ApplicationController inherits ActionController::Base #81

Closed SamMolokanov closed 7 years ago

SamMolokanov commented 7 years ago

Hi there!

In modern Rails versions all controllers inherit from ApplicationController, but GrapeSwaggerRails::ApplicationController inherits ActionController::Base. By this reason methods that are defined at ApplicationController are not accessible from GrapeSwaggerRails context.

For example, if we have defined a method current_user in Rails ApplicationController

# application_controller.rb

class ApplicationController < ActionController::Base

  def current_user
    User.find(session[:user_id])
  end

end

If we use method current_user in a before_filter hook as described here, we have an error:

  GrapeSwaggerRails.options.before_action do |request|
    GrapeSwaggerRails.options.api_key_default_value = current_user.api_token
  end
  undefined local variable or method `current_user' for #<GrapeSwaggerRails::ApplicationController:0x007f88a1c5ac48>

This problem could be solved if GrapeSwaggerRails::ApplicationController inherits standard ApplicationController

Thanks for reading this!

dblock commented 7 years ago

Seems reasonable. Maybe try to contribute this?

SamMolokanov commented 7 years ago

I have thought again about inheriting and found that GrapeSwaggerRails is mounted as Rails Engine. At this point dependency injection from main application into an engine does not look like a good idea :) So, may be using of constraint-based restriction in routes would be good enough:

# config/routes.rb

# for Devise
authenticate :user do
  mount GrapeSwaggerRails::Engine => '/swagger'
end

# for request-based auth logic
constraints lambda { |request| SomeCustomAuthLogic.allow?(request) } do
  mount GrapeSwaggerRails::Engine => '/swagger'
end