I have a controller action that responds to the same root in two formats - html and json. But the code that runs for the html response is completely different than the one for the json response..
Now I have something like
def index
result_html = ...
result_json = ...
respond_to |format|
format.html
format.json { result = result_json.limit(10) }
end
end
and I would like to have it like
def index.html
result_html ...
end
and
def index.json
result_json ...
end
What would be the best way to organize it?
May be something like this will work for you.
def index
respond_to |format|
format.html { index_html}
format.json { index_json }
end
end
def index_html
...
end
def index_json
...
end
You can test for the format with request.format.symbol then when :json call your json action or when :html call your html action.
Related
I want to make an ajax search query by a client's name, so I'm using a like clause (see this question). I was thinking of using the index action to respond to json format from clients_controller but I'm already using it to repond to html format and at the same time paginates my listed rows with will_paginate and will_paginate-bootstrap.
What is the best way? making a new method to respond to json format or should I use the index one with format? and How to do that?
I'm new with ruby on rails
clients_controller.rb
def index
respond_to do |format|
format.html
{
#something like this I know that I would return me a syntax error
#client = Client.paginate(:page => params[:page])
}
format.json
{
#something like this I know that I would return me a syntax error
#client = Client.where("client_name LIKE ? ", "%#{params[:client_name]}%" )
}
end
end
def other_method
#client = Client.where("client_name LIKE ? ", "%#{params[:client_name]}%" )
respond_to do |format|
format.json {...}
end
end
In my opinion, you should keep only your index action and just accumulate the scopes on your #client variable.
Remember that your SQL query is only sent to the database when performing an Array method like each on your variable, not before.
So you can write something like:
def index
#client = Client.all
if params[:client_name].present?
#client = #client.where("client_name LIKE ? ", "%#{params[:client_name]}%")
else
#client = #client.paginate(page: params[:page])
end
respond_to do |format|
format.html
format.json
end
end
You should create a new action with some fruitful name like search or search_by_client_name . It will solve your issue also and you will stick with rails restful routing.
If you want index action to serve both request then you can do something like this:
def index
#client = Client.paginate(:page => params[:page])
respond_to do |format|
format.html
format.json do
client = Client.where("client_name LIKE ? ", "%#{params[:client_name]}%"
render json: { client: client }
end
end
end
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.
This is the code from internet and I am having trouble understanding what does respond_to, format.html and format.js do in the controller.
def create
#review = Review.create!(params[:review])
flash[:notice] = "Thank you for reviewing this product"
respond_to do |format|
format.html { redirect_to #review.product }
format.js
end
end
Thank you for your time.
Ramya
respond_to(*types, &block) public
Without web-service support, an action which collects the data for displaying a list of people might look something like this:
def index
#people = Person.find(:all)
end
Here’s the same action, with web-service support baked in:
def index
#people = Person.find(:all)
respond_to do |format|
format.html
format.xml { render :xml => #people.to_xml }
end
end
What that says is, "if the client wants HTML in response to this action, just respond as we would have before, but if the client wants XML, return them the list of people in XML format." (Rails determines the desired response format from the HTTP Accept header submitted by the client.)
Supposing you have an action that adds a new person, optionally creating their company (by name) if it does not already exist, without web-services, it might look like this:
def create
#company = Company.find_or_create_by_name(params[:company][:name])
#person = #company.people.create(params[:person])
redirect_to(person_list_url)
end
Here’s the same action, with web-service support baked in:
def create
company = params[:person].delete(:company)
#company = Company.find_or_create_by_name(company[:name])
#person = #company.people.create(params[:person])
respond_to do |format|
format.html { redirect_to(person_list_url) }
format.js
format.xml { render :xml => #person.to_xml(:include => #company) }
end
end
If the client wants HTML, we just redirect them back to the person list. If they want Javascript (format.js), then it is an RJS request and we render the RJS template associated with this action. Lastly, if the client wants XML, we render the created person as XML, but with a twist: we also include the person’s company in the rendered XML, so you get something like this:
http://apidock.com/rails/ActionController/MimeResponds/InstanceMethods/respond_to
i'm quite new to rails. i'm trying to set a rails controller's response type to xml, but not having much luck. i could certainly afford to better understand how respond_to and respond_with work.
here's what my controller looks like:
class ResponsesController < ApplicationController
respond_to :xml
def index
require 'rubygems'
require 'telapi'
ix = Telapi::InboundXml.new do
Say('Hello.', :loop => 3, :voice => 'man')
Say('Hello, my name is Jane.', :voice => 'woman')
Say('Now I will not stop talking.', :loop => 0)
end
respond_with do |format|
format.xml { render }
end
puts ix.response
end
end
this leads to an http retrieval failure. can someone advise me how to how i can fix the controller and set its response type to xml? also, a cogent 1-2 liner of how respond_to and respond_with work would be awesome!
thanks everyone.
replace
respond_with do |format|
format.xml { render }
end
with
respond_with(ix)
There are 2 ways of rendering a xml. Example 1 uses respond_to that means "every single method will use xml and use the object parse in from respond_with"
Example 2 uses respond_to that means "use the block below to declare what type of respond and the object to be parse"
example 1:
class ResponsesController
respond_to :xml #respond_to A
def index
respond_with(#asd) # respond_with A
end
end
example 2:
def ResponsesController
def index
respond_to do |format|
format.xml { render xml: #asd}
end
end
end
http://blog.plataformatec.com.br/2009/08/embracing-rest-with-mind-body-and-soul/
I am experimenting with Rails and was wondering what's needed to allow/add support for JSON requests?
I have a vanilla installation of Rails 2.3.5 and the default scaffolding seem to provide support for HTML & XML requests but not JSON.
class EventsController < ApplicationController
# GET /events
# GET /events.xml
def index
#events = Event.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #events }
end
end
# GET /events/1
# GET /events/1.xml
def show
#event = Event.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #event }
end
end
...
I'm new to this but it would appear as though i would need to add a format line in each method along the lines of:
format.js { render :js => #event.json }
couldn't this be done automatically? perhaps there's a template somewhere i need to update...or a flag i can set? Or perhaps, and most likely, I've missed the boat entirely?!?
You do:
format.json {render :json=>#event}
That will render the default activerecord JSON for the model
The option of ease of use is that you can write a private method which takes the format object and an object to render and then, based on the format, renders different things. Example:
class MyController<ApplicationController
def show
#event=Event.find(params[:id])
respond_to do {|format| myRenderer(format,#event)}
end
...
private
def myRenderer(fmt,obj)
fmt.json {render :json=>obj}
fmt.html
fmt.xml {render :xml=>obj}
end