Is there something like:
respond_to do |format|
format.html || format.xml do
#big chunk of code
end
end
I would like to do that for DRY's sake.
Respond_to actually allows you to specify your common block for different formats by using any:
format.any(:js, :json) { #your_block }
You can use a format like this:
class PeopleController < ApplicationController
respond_to :html, :xml, :js
def index
#people = Person.find(:all)
respond_with(#people) do |format|
format.html
format.xml
format.js { #people.custom_code_here }
end
end
end
Which would achieve what you are looking for, if you have a situation that is more complex let me know. See this article on the respond_with method for more help.
when you
respond_to do |format|
format.html do
#block
end
format.xml do
#block
end
end
or you
respond_to do |format|
format.html { #block }
format.xml { #block }
end
you are taking advantage of ruby blocks, which are evaluated as Procs. Therefore you could do
respond_to do |format|
bcoc = Proc.new do
# your big chunk of code here
end
format.html bcoc
format.xml bcoc
end
but perhaps you could move some of that logic into your data structure?
Related
I have a rails controller where every action has the same respond_to block for every action, eg:
def some_action
respond_to do |format|
format.html { redirect_to :back }
format.js { render layout: false }
end
end
Is there a way that I can set this as the default response for all actions? I know that I can use
respond_to :html, :js
at the top of the controller, but can this be used to set the specific responses for each format?
Going though respond_with and respond_to documentation and source code. You can either
Use respond_to
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
flash[:notice] = 'User was successfully created.'
format.html { redirect_to(#user) }
format.xml { render xml: #user }
else
format.html { render action: "new" }
format.xml { render xml: #user }
end
end
end
OR respond_with
respond_to :html, :xml
def create
#user = User.new(params[:user])
flash[:notice] = 'User was successfully created.' if #user.save
respond_with(#user)
end
A work around is to create your own custom respond method, or manually check for the mime type as follows:
****NOTE: this is a really bad practice, I recommend sticking to conventions.
def some_action
render json: {"a" => "s"} if request.format.json?
render :some_action if request.format.html?
end
If you want all actions to respond exactly the same, move the respond_to block into a method.
def some_action
# do things
respond
end
def another_action
# do more things
respond
end
def special_action
# do special things
respond
end
private
def respond
respond_to do |format|
format.html { redirect_to :back }
format.js { render layout: false }
end
end
This will DRY up your controller, which I assume was the question.
I have one js file show.js that is renderd for the action def show:
def show
....
respond_to do |format|
format.html
format.js
end
end
My question is how can I change the respond_to block, so that it does not respond with show.js but for example with newshow.js? I ask because I would like to render different js dependent on the params! Thanks! I use Rails 4.
I believe that this one would work:
respond_to do |format|
format.html
format.js { render :newshow }
end
Presently I'm using respond_to like this.
respond_to do |format|
format.html {render layout: false }
end
I know a sentence like respond_to {| format | format.html } can be written respond_to :html.
But how can I write without first block if format.html also have a block argument?
I want to write like respond_to :html, {render layout: false }.
Could it be you have this confused with respond_with?
class PeopleController < ApplicationController
respond_to :html
def index
#people = Person.all
respond_with #people
end
end
respond_with can be configured just as respond_to:
respond_with(#people) do |format|
format.html { render layout: false }
end
See the API documentation or this Railscast for more information about respond_with.
I have a controller "UserController" that should respond to normal and ajax requests to http://localhost:3000/user/3.
When it is a normal request, I want to render my view. When it is an AJAX request, I want to return JSON.
The correct approach seems to be a respond_to do |format| block. Writing the JSON is easy, but how can I get it to respond to the HTML and simply render the view as usual?
def show
#user = User.find(params[:id])
respond_to do |format|
format.html {
render :show ????this seems unnecessary. Can it be eliminated???
}
format.json {
render json: #user
}
end
end
As per my knowledge its not necessary to "render show" in format.html it will automatically look for a respective action view for ex : show.html.erb for html request and show,js,erb for JS request.
so this will work
respond_to do |format|
format.html # show.html.erb
format.json { render json: #user }
end
also, you can check the request is ajax or not by checking request.xhr? it returns true if request is a ajax one.
Yes, you can change it to
respond_to do |format|
format.html
format.json { render json: #user }
end
The best way to do this is just like Amitkumar Jha said, but if you need a simple and quick way to render your objects, you can also use this "shortcut":
def index
#users = User.all
respond_to :html, :json, :xml
end
Or make respond_to work for all the actions in the controller using respond_with :
class UserController < ApplicationController
respond_to :html, :json, :xml
def index
#users = User.all
respond_with(#users)
end
end
Starting from Rails 4.2 version you will need to use gem responder to be able to use respond_with.
If you need more control and want to be able to have a few actions that act differently, always use a full respond_to block. You can read more here.
respond_to do |format|
format.html
format.xml { render :xml => #mah_blogz }
end
respond_to do |format|
format.js
end
What's this respond_to, format.html, format.xml and format.js? What's their purpose and how do they work?
Here's the link to the documentation
http://api.rubyonrails.org/classes/ActionController/MimeResponds/ClassMethods.html#method-i-respond_to
Its a way of responding to the client based on what they are asking for, if the client asks for HTML, Rails will send back HTML to the client, if they ask for XML then XML.
Say you are doing this:
class UsersController < ApplicationController
def create
#
#your code
#
respond_to do |format|
format.xml {render :xml => xxx}
format.json {render :json => xxx}
format.html {render xxx}
end
end
def edit
#
#your code
#
respond_to do |format|
format.xml {render :xml => xxx}
format.json {render :json => xxx}
format.html {render xxx}
end
end
end
rather do:
class UsersController < ApplicationController
respond_to :xml, :json, :html
def create
#
#your code
#
respond_with xxx
end
def edit
#
#your code
#
respond_with xxx
end
end
and thats how you keep the code DRY (Dont Repeat Yourself)