In Rails, How to Access Response.Body in a Action Before It Returns

In rails, can I access response.body in a action before it returns?

You can write a rack middleware to do such kind of replacements. Code for the rack is.

module Dump
require 'rack'

class Response
def initialize(app)
@app=app
end

def call(env)
res=@app.call(env)
res.body #change this and but also update res.length and header["Content-Length"]
return res
end
end
end

include it in some file, lets call it dump_response.rb in RAILS_ROOT/lib folder.
And line

use Dump::Response

in config.ru

Is there a way to wrap the response of all controller methods in a json object in application_controller.rb?

Option-1: We have something similar in our setup, what we do is, that we have a method named render_response in our base_api_controller file. Which looks something like:

  def render_response(render_params)
# controller_name, action_name will give you controller and action which rendered the response.
# so you can decide weather to process anything or just render

render_params[:json] = { payload: render_params[:json] }
render render_params
end

And your controller action will convert to something like:

return_obj = { key: value }
render_response json: return_obj

Personally(and obviously) I like first approach because it is explicit and looking at the controller code gives us the information that we are processing the response further.

Option-2: If you don't like replacing render with render_response you can follow this guide to setup a rack middleware, which is also dead simple. but you will have to place checks of controllers if you don't want to do any updates for some specific controller actions. And also note that it will be automatic, so without anyone noticing(lets see someone completely new to your code) it will be changing the response. Which i personally don't like much.

Get HTTP POST Response in Rails Controler

The variable resp represents the response object. You can use the #body method to get the body of the response as String.

If the body is a String serialization of a JSON, simply parse it back to fetch the elements.

hash = JSON.parse(resp.body)
hash['token']
# => ...

How to return truly empty body in rails? i.e. content-length 0

This appears to work

render :text => ""

For Rails 3, you could use:

render :nothing => true

In Rails 5, render :nothing => true is deprecated (planned for removal in 5.1)

Use

def action
head :ok
end

Credit to this question for the Rails 5 solution.

Webhook : how to display the response in my view

params instead of response.body

def webhooks
render json: params, status: 200
puts params
end

How does Rails calculate the response code for actions

See inline comments below

if @user.update(user_params)
format.html { redirect_to @user, notice: 'User was successfully updated.' }
# 302, the save was successful but now redirecting to the show page for updated user
# The redirection happens as a “302 Found” header unless otherwise specified.

format.json { head :no_content }
# 204, successful update, but don't send any data back via json

else
format.html { render action: 'show' }
# 200, standard HTTP success, note this is a browser call that renders
# the form again where you would show validation errors to the user

format.json { render json: @user.errors, status: :unprocessable_entity }
# 422, http 'Unprocessable Entity', validation errors exist, sends back the validation errors in json

end

if you look at format.json { render json: @user.errors, status: :unprocessable_entity } it uses the status option on render to be explicit about the HTTP status code
so you can do render action: 'show', status: 422 or render action: 'show', status: :unprocessable_entity if you wanted to (you probably don't) - and render defaults to 200 Ok (rails uses a symbol :success to alias :ok as well

see also:

  • http://api.rubyonrails.org/classes/ActionController/Redirecting.html
  • http://api.rubyonrails.org/classes/ActionController/Head.html

see Getting access to :not_found, :internal_server_error etc. in Rails 3
in your console Rack::Utils::HTTP_STATUS_CODES to view all status codes (the values are symbols in rails), i.e. Unprocessable Entity is :unprocessable_entity

Rails Controller -- just return the processed data (dont load into a view)

Some options to consider:

Render just the raw string as the http response body:

render :text => content

Render a view without the default surrounding layout:

render :layout => false

In that case your view could just be:

<%= @content %>

Or render the content as json:

render :json => { :content => content }


Related Topics



Leave a reply



Submit