Basic action
def index
@posts = Posts.all
render :index
end
When a client makes a request it generally will expect HTML as response to an action call. What if the client would expect json? The following example uses respond_to
to determine a match for this service.
def index
@posts = Posts.all
respond_to do |format|
format.html { render xml: @post }
format.json { render json: @post }
format.xml { render xml: @post }
end
end
Here we are going to implement a create action for a new post. Lets pretend we’re using strong params along with devise for a current_user helper.
def create
@user = current_user
@post = @user.post.find_or_create_by(post_params)
redirect_to post_path @post
end
To be able to send back the appropriate format we once again use a respond_to
block.
def create
@user = current_user
@post = @user.post.find_or_create_by(post_params)
respond_to do |format|
format.html { redirect_to (post_path @post) }
format.js
format.json { render json: @post.to_json(include: @user) }
end
end
If the client wants HTML we redirect them to the post list. If they want JavaScript, then it’s an ajax request and we render the JavaScript template associated with this action. Lastly, if the client wants JSON, we render the created person as JSON, but with a difference. We will also include the current user in the response. Sort of like this.
{
posts: [
{
id: 1,
title: "A new post!"
description: "the greatest post ever."
user: {
id: 99,
name: 'Sam'
}
}
]
}
What happens if some of the responses are being repeated? To be more DRY you can do this.
def index
@posts = Post.all
respond_to do |format|
format.html
format.any(:json, :xml) { render request.format.to_sym => @posts }
end
end
The format in respond_to is actually an object of ActionController::MimeResponds::Collector
class. This object works as a container to store available responses that can be called on by any of the mime-type-specific methods such as html, xml
etc.
It makes a subsequent call to negotiate_format(request)
on the backend and enables the Collector to determine which mime-type specifically it should respond with. When it finds a match it calls response
.