30

I'm trying to write an Ember application in Rails 4, and have decided to go with rails-api for the api controllers, while keeping the application controller intact for a few pages that aren't part of the single-page app. To put it in more concrete terms, here are my controllers:

app/controllers/application_controller.rb:

class ApplicationController < ActionController::Base
  protect_from_forgery
end

app/controllers/sample_controller.rb:

class SampleController < ApplicationController
  # my methods
end

app/controllers/api/v1/api_controller.rb:

class Api::V1::ApiController < ActionController::Api
  include ActionController::MimeResponds
end

app/controllers/api/v1/sample_controller.rb:

module Api::V1
  class SampleController < ApiController
    respond_to :json

    # my methods

  end
end

My application.html.slim contains the following line:

== render partial: "flash_msgs" unless flash.blank?

The inclusion of which results in the following error:

undefined method 'flash' for #< ActionDispatch::Request:0x007f99f41d8720 >

Per discussion on this thread, it seems that the culprit could be rails-api, but I'm not entirely convinced given the inheritance I've set up. Any suggestions?

Promise Preston
  • 24,334
  • 12
  • 145
  • 143
Jonathan Bender
  • 1,911
  • 4
  • 22
  • 39

4 Answers4

46

Not sure but maybe you need to include the ActionDispatch::Flash middleware to support the flash. Using:

config.middleware.use ActionDispatch::Flash

The docs says:

ActionDispatch::Flash: Supports the flash mechanism in ActionController.

I hope it helps

Marcio Junior
  • 19,078
  • 4
  • 44
  • 47
  • Thanks for that, I wasn't expecting `rails-api` to be so heavy-handed in its removal of middleware, and to only really affect the controllers. – Jonathan Bender Oct 26 '13 at 00:25
  • Thank you! I got the same problem with gem `api-pagination` and it fixed it! – micred Feb 23 '15 at 15:07
  • With the changes in the gem http://stackoverflow.com/a/23053260/827770 is the correct answer. – Qaiser Wali May 22 '15 at 17:28
  • 14
    This goes in application.rb, "and if you don't know, now you know" – zero_cool Jun 15 '15 at 18:01
  • @QaiserWali That's not entirely accurate. The answers below make assumptions about your application (they add back the full stack of middleware or change what's considered "navigational") that aren't always accurate. This answer is still correct for the original use case. – Jonathan Bender Aug 18 '15 at 23:51
  • What if I don't want the flash middleware? Is there a way to remove the Flash mechanism? – LordAlpaca Jan 18 '19 at 15:27
34

See: https://github.com/plataformatec/devise/issues/2775

Inside devise.rb change

config.navigational_formats = ['*/*', :html]

to:

config.navigational_formats = [:json]

or just [ ]

cbron
  • 4,036
  • 3
  • 33
  • 40
  • 5
    For anyone using the excellent `devise_token_auth` instead plain vanilla `devise`, you'll need to create this file at `config/initializers/devise.rb`. – Aaron Gray Aug 18 '15 at 22:50
  • 1
    Thanks Aaron. For `devise_token_auth` also wrap it in `Devise.setup do |config| ... end` – Meekohi Jan 24 '17 at 15:23
  • Hi, I used the [] instead of [:json]. There are many differences between API only rails app ? – Marco Sanfilippo Feb 14 '17 at 17:25
32

If you're like me and creating an API on top of an existing application, you can add this to your config/application.rb file:

config.api_only = false

Chuck Callebs
  • 16,293
  • 8
  • 56
  • 71
  • 4
    It should be noted that this option will add back *all* of the middleware that `rails-api` removes. While this may be what you're looking for, just something to be aware of. – Jonathan Bender Aug 18 '15 at 23:52
  • 3
    Why are people upvoting this, I have no idea. You've just turned your rails-api app into a rails app. – gangelo Nov 16 '17 at 16:39
  • @gangelo My answer was directed at folks not using `rails-api`. Rails handles this a lot better now. – Chuck Callebs Jan 18 '18 at 14:00
0

well, in my case my API mode rails app I had this code in one of my controller:

protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' }

due to which handle_unverified_request was getting called that has this small piece of code request.flash = nil which was raising Undefined method 'flash' for ActionDispatch::Request for me.

Dealt with it by replacing protect_from_forgery with skip_before_action :verify_authenticity_token

Talha Meh
  • 487
  • 7
  • 20