Rails 4 + Devise + Rails API: undefined method 'flash'

瘦欲@ 提交于 2021-02-07 07:14:13

问题


I have an existing Rails 4 application which uses Devise and Omniauth. I'm trying to modifying my existing app to develop an API(I mean I will have my web app as it is and also I want an API for mobile app) but I'm having a hard luck.

I'm following the steps that are listed in Rails-API under "For already existing apps" section and now I'm getting the below error

undefined method `flash' for #<Devise::SessionsController:0x000000098221d0>

The error pops at this line <% unless flash.blank? %> in views/devise/sessions/new.html.erb

I tried putting config.middleware.use ActionDispatch::Flash in /config/application.rb but the error exists.

I also have config.api_only = false in /config/application.rb

Below is my code

#app/controllers/application_controller.rb
class ApplicationController < ActionController::API
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  include ActionController::RequestForgeryProtection
  include Pundit
  include ActionController::Serialization
  include ActionView::Layouts
  include ActionController::ImplicitRender
  protect_from_forgery with: :null_session

  ----some other code------
end

--------xxxxxx-----------

#/config/application.rb
require File.expand_path('../boot', __FILE__)

require 'rails/all'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups, :default, :assets, Rails.env)



module SampleApp
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

    # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
    # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
    # config.time_zone = 'Central Time (US & Canada)'

    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
    # config.i18n.default_locale = :de

    # For Custom Error Handling
    config.exceptions_app = self.routes

    config.middleware.use ActionDispatch::Flash

    # To use rails default middleware for api
    config.api_only = false

    config.generators do |g|
        g.test_framework :rspec,
          :fixtures => true,
          :view_spec => false,
          :helper_specs => false,
          :routing_specs => false,
          :controller_specs => true,
          :request_specs => true
        g.fixture_replacement :factory_girl, :dir => "spec/factories"
    end
  end
end

-------xxxxxxx-------

#routes.rb
Rails.application.routes.draw do

  devise_for :admin_users, ActiveAdmin::Devise.config
  ActiveAdmin.routes(self)
  # TODO add staging/dev password lock to site
  # if Rails.env.staging?
  #   mount Lockup::Engine, at: '/lockup'
  # end

  # TODO come back and fix so admin user (active admin) and regular user can be logged in at same time
  get '/', to: 'users#index', constraints: lambda { |request| request.env['warden'].user && request.env['warden'].user.role == 'admin' }
  #root to: 'visitors#index'

  devise_for :users, :controllers => { :registrations => "registrations", :omniauth_callbacks => "users/omniauth_callbacks" }

  devise_scope :user do
    root to: "devise/sessions#new"
  end

  namespace :api do
    namespace :v1  do
      devise_for :users
    end
  end
  #some other unnecessary routes
end

Question:

The Rails-API says this

If you want to use the Rails default middleware stack (avoid the reduction that rails-api does), you can just add config.api_only = false to config/application.rb file.

Since I have included config.api_only = false to config/application.rb and considering the fact that ActionDispatch::Flash ships with Rails default, why I'm getting that error? What do I need to get rid of that?


回答1:


I tried a lot of suggestions before I boiled it down to these steps. It worked for me. Hope this helps.

Add the following lines in config/routes.rb:

devise_for :users, defaults: { format: :json }

Add the following lines in config/initializers/devise.rb:

config.navigational_formats = [:json]

Add the following lines in config/application.rb:

config.api_only = true
config.middleware.use ActionDispatch::Flash



回答2:


Devise will only try to set the Flash if it thinks you are expecting your answer back in HTML.

I suspect - the only issue is - that when you called the API you didn't pass in the following headers:

"Accept": "application/json"



回答3:


If you try the answer above and still get that same error, try the following.

  1. Restart your rails server

If error still persists:

  1. In the application.rb file change the line config.api_only = true that you just added to false:

    config.api_only = false
    


来源:https://stackoverflow.com/questions/33560898/rails-4-devise-rails-api-undefined-method-flash

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!