10

I'm implementing a simple API in my application to communicate with an Android application. I'm trying to use AbstractController::Metal mainly for performance. The problem I'm having is that render is ignoring the status option that I'm passing.

Very simple example:

class Api::V1::ApiController < ActionController::Metal
  include AbstractController::Rendering
  include ActionController::Renderers::All
  include ActionController::RackDelegation
  include ActionController::MimeResponds
end

class Api::V1::SessionsController < Api::V1::ApiController
  def show
    render status: :unauthorized   # using 401 yields the same result
  end
end

Calling

curl -v -X GET http://app.dev:3000/api/v1/sessions.json

I'd expect to receive a 401 but instead I get a 200 OK:

> GET /api/v1/sessions.json HTTP/1.1
> User-Agent: curl/7.30.0
> Host: app.dev:3000
> Accept: */*
> 
< HTTP/1.1 200 OK

Any ideas? Overwriting response.status is the only work around I've found so far, but honestly it looks like an ugly hack.

Thank you in advance for your insights.

Felipe Koch
  • 288
  • 2
  • 8
  • are you sure that `/api/v1/sessions.json` goes to your action `show` action? and also looks like instead of `render status: :unauthorized` should be `render nothing: true, status: 401` – Igor Guzak Aug 27 '14 at 18:53
  • @IS04 Yes it goes to show because in my routes I have resource :sessions (instead of resource**s**). I've also tried render nothing and got the same result (regarding the status, the response's body was empty). – Felipe Koch Aug 27 '14 at 23:08
  • 1
    I'm having the same problem with ActionController::Metal -- any insights you uncovered on it? – Michael Oct 03 '14 at 02:58
  • @Michael No, I'm overwriting response.status :( – Felipe Koch Oct 03 '14 at 21:49
  • @FelipeKoch Okay, good to know. Sad that it has to come to that. – Michael Oct 05 '14 at 15:04
  • Check out the solution for the issue here : https://stackoverflow.com/a/70998414/7674579 – Kishan Verma Feb 05 '22 at 13:28

3 Answers3

1

To render nothing and return code 401 use:

render nothing: true, status: :unauthorized
Kamen Kanev
  • 181
  • 2
  • 12
0

use head ActionController::Head

class Api::V1::SessionsController < Api::V1::ApiController
  def show
    head :unauthorized
  end
end
Zhaohan Weng
  • 378
  • 1
  • 4
  • 10
0

I had the same issue with the example code shown below. This was working with ActionController::Metal in Rails 3, and started failing after upgrading to Rails 4.2.4:

# config/routes.rb
get :unauthorized, to: 'unauthorized#respond'     

# app/controllers/unauthorized_controller.rb
class UnauthorizedController < ActionController::Metal
  def respond
    head :forbidden
  end
end

# spec/controllers/unauthorized_controller_spec.rb
describe UnauthorizedController do
  it 'should respond with 403 forbidden' do
    get :respond, {}, {}

    expect(response.status).to be == 403
  end
end

The test was failing after the upgrade. So to solve this I had to change

class UnauthorizedController < ActionController::Metal

to

class UnauthorizedController < ActionController::Base

ddreliv
  • 181
  • 1
  • 11