Passing multiple parameter in respond_to block in rails - ruby-on-rails

In my line_items_controller in create action I have following code
format.xml { render 'carts/_cart.html.erb',
:status => :created, :location => #line_item }
I need to send #cart as well here. I tried this
format.xml { render 'carts/_cart.html.erb', #cart,
:status => :created, :location => #line_item }
But this is not working. Could you please tell me how to do this?

Same way as :location
format.xml { render 'carts/_cart.html.erb', :status => :created, :location => #line_item, :cart => #cart }

Notwithstanding you're trying to create an xml response with an html file, have you considered this:
format.xml { render :partial => 'carts/cart', :status => :created, :location => #line_item }
This should handle #cart in the partial, as #cart is an instance var
Here is a more in-depth description of the respond_to block which you may be able to glean some nuggets from
I also found this resource for you: Rails format.xml render and pass multiple variables. The epic reply on there basically suggests that you define your instance variables in your function, and then use them in the action.xml.erb file, like this:
#app/controllers/home_controller.rb
def index
#users = ...
#another = "Hello world!"
# this `respond_to` block isn't necessary in this case -
# Rails will detect the index.xml.erb file and render it
# automatically for requests for XML
respond_to do |format|
format.html # index.html.erb
format.xml # index.xml.erb
end
end
#app/views/home/index.xml.erb
<?xml version="1.0" encoding="UTF-8"?>
<document>
<%= #users.to_xml # serialize the #users variable %>
<extra_string><%= #another %></extra_string>
</document>
That's all I got right now

Related

How to convert this respond_to options to use Rails 3 version?

respond_to do |format|
if #user.save
format.js { render :nothing => true, :status => :ok, :location => #user }
else
format.js { render :json => #user.errors, :status => :unprocessable_entity }
end
end
All options I've tried (like putting respond_to :js at the top of controller, etc) don't quite work the way as in this.
Rails 3 Format:
Use respond_to :json and respond_with(#user)
respond_to :json # You can also add , :html, :xml etc.
def create
#user= User.new(params[:user])
#---For html flash
#if #user.save
# flash[:notice] = "Successfully created user."
#end
respond_with(#user)
end
# Also, add :remote => :true, :format => :json to the form.
Try using format.json instead of format.js in your controller and :remote => :true, :format => :json in corresponding form.
Though, I'm not quite sure whether format.json or format.js should be used in that case. As default scaffolding from Rails 3 generates controllers with format.json and you're doing render :json in response I believe format.json is the right way to go. And format.js should be used when you return a piece of JS that should be executed.
The URL your are requesting should end with .json like this: /controller/action.json
If that is not possible:
You should set the 'accepts' parameter to 'application/json' while sending the ajax request.
Search for how to use 'accepts' here: http://api.jquery.com/jQuery.ajax/
And in the server side:
format.json { render :json => #user.errors, :status => :unprocessable_entity }

Multiple JSON responses in a single Rails controller action

I have my show method on a controller in my application and in the response block I have
respond_to do |format|
format.html { render :layout =>'placing', :next_days => #next_days}# show.html.erb
format.xml { render :xml => #artist }
format.json { render :partial => "places/show.json", :artist => #artist } }
end
This, generates a json output based in the show.json partial in /places/1.json for example, but what if I want one more json output, like /places/alternative_1.json? How can I do that if there is already a json format block inside respond_to?
Any help is appreciated!
Cheers!
Then you will have to make some logic inside your format.json block changing what you are associating to :partial (currently is "places/show.json"), or create another route...
As format.json { render ... } is normal Ruby code, you could do something like:
format.json do
json_partial = json_for_this_case #example
render :partial => json_partial, :locals => {:artist => #artist}
end

What does `:location => ...` and `head :ok` mean in the 'respond_to' format statement?

I am using Ruby on Rails 3 and I would like to know what the :location => ... and head :ok statements mean in following code, how they work and how I can\should use those.
respond_to do |format|
format.xml { render :xml => #user, :status => :created, :location => #user }
end
respond_to do |format|
format.xml { head :ok }
end
render ... :location => #user will set the HTTP location header to inform the client of the location of the newly created resource (that is, its URL)
head :ok sets render to return an empty response (so just the header, no body) with status 200. head :ok is shorthand for render nothing: true, status: :ok.
Here's a list of all the :status options you can use for setting the appropriate status code.

Ruby on Rails revise instead of edit

I am still a bit new to RoR, and am using scaffolding to generate CRUD interfaces for data.
I am using devise for user authentication, and want to allow a user that owns a specific entry to edit or delete, but protect that data from other users. However, I would like to allow a different user to revise or create new versions.
So if a user that attempts to edit should appear as if they are editing, but when they submit, the controller should actually generate a new entry (and potentially specify the parent_id of the entry it derived from).
Any help on implementation is greatly appreciated.
Also look into Ancestry, it's a really nice library to help with versioning.
Here is my solution that I came up with. I am a ruby newb, so I assume that I can just call the create function with the same params but wasn't sure how to do that, so I just duplicated code:
def update
#section = Section.find(params[:id])
if #section.owner == current_user.id
respond_to do |format|
if #section.update_attributes(params[:section])
format.html { redirect_to(#section, :notice => 'Section was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #section.errors, :status => :unprocessable_entity }
end
end
else
# REVISE
#childsection = Section.new(params[:section])
respond_to do |format|
if #childsection.save
format.html { redirect_to(#childsection, :notice => 'Section was successfully revised.') }
format.xml { render :xml => #childsection, :status => :created, :location => #childsection }
else
format.html { render :action => "new" }
format.xml { render :xml => #childsection.errors, :status => :unprocessable_entity }
end
end
end
end

In Rails 3, respond_to and format.all works differently than Rails 2?

the code
respond_to do |format|
format.html
format.json { render :json => #switches }
format.xml { render :xml => #switches.to_xml }
format.all { render :text => "only HTML, XML, and JSON format are supported at the moment." }
end
the above will work in Rails 2.2.2. But in Rails 3, getting controller/index.html or index on the browser will both fall into the last line: "only HTML and JSON format are supported at the moment."
The only Rails doc I can find on this is
http://api.rubyonrails.org/classes/ActionController/MimeResponds/ClassMethods.html#method-i-respond_to
which current only states:
respond_to :html, :xml, :json
but they need separate templates for json and xml, and can't handle the "only HTML and JSON format are supported at the moment" case.
In rails3 you would write:
respond_with(#switches) do |format|
format.html
format.json { render :json => #switches }
format.xml { render :xml => #switches }
format.all { render :text => "only HTML, XML, and JSON format are supported at the moment." }
end
But this only works in correspondence with a respond_to block at the top of the file, detailing the expected formats. E.g.
respond_to :xml, :json, :html
Even in that case, if anybody for instance asks the js format, the any block is triggered.
You could also still use the respond_to alone, as follows:
#switches = ...
respond_to do |format|
format.html {render :text => 'This is html'}
format.xml {render :xml => #switches}
format.json {render :json => #switches}
format.all {render :text => "Only HTML, JSON and XML are currently supported"}
end
Hope this helps.
You may find it useful to watch this episode of railscasts, which illustrates the changes to controllers in Rails 3 and in particular the changes to the responder class (putting respond_to in the controller class itself and only using respond_with #object in the action):
http://railscasts.com/episodes/224-controllers-in-rails-3
The following works for me. I believe you have to specify the "render" part for html explicitly or it will use the format.any.
respond_to do |format|
format.html { render :html => #switches }
format.json { render :json => #switches }
format.xml { render :xml => #switches }
format.all { render :text => "we only have html, json, and xml" }
end

Resources