There is another respond_to for the usual case, and a special case when a param[:top] is passed in, so there is another respond_to earlier in the code:
respond_to do |format|
format.html { render :top_page_analytics }
format.json { render :json => #analytics }
format.xml { render :xml => #analytics }
return
end
but the above code actually gave a strange error for missing template for json, and further debug leading to:
respond_to do |format|
format.html { render :top_page_analytics }
format.json { render :json => #analytics }
format.xml { render :xml => #analytics }
end
return
which fixes the bug. The return is needed so that there will be no "double render error" because the program will flow to the other respond_to. But I wonder the strange syntax of respond_to, looking somewhat like a case statement, may cause error like that at the top?
The return can't go there because you're passing a block. The block isn't executed in the immediate context of the controller action. When you return from the block, you're actually returning from the function yielding (respond_to), not the controller action.
Related
I recently updated a controller from a plain
render :json => #something
to
respond_to do |format|
format.html {
redirect_to #something
}
format.json {
puts "found json format"
format.json { render json: #something, status: :created }
}
end
But, now I'm getting ActionView::MissingTemplate errors. My question is, if I use the respond_to do |format| block, am I required to use a template? What if I just want to return plain json?
Btw, the puts statement in the json respond_to block is being called successfully.
I think the problem is puts being called inside of your format.json block and the nesting of format.json inside of it's own block. Try removing both (as below).
respond_to do |format|
format.html {
redirect_to #something
}
format.json {
puts "found json format"
format.json { render json: #something, status: :created }
}
end
Try:
respond_to do |format|
format.html { redirect_to #something }
format.json { render json: #something, status: :created }
end
You are telling that you accept HTML and JSON formats. Since your request comes from HTML you'll have the HTML template rendered.
If you want to return only JSON remove that line from your code. Also check the docs on respond_to.
Probably you already know it, but there's a guide on Layouts and Rendering.
Remove the format.json part from within the json rendering block (you have an unnecessary block within your block):
respond_to do |format|
format.html {
redirect_to #something
}
format.json {
render json: #something, status: :created
}
end
I think the reason your code is prompting an error it's because you have
format.json {
format.json { render json: #something , status: :created }
}
You should have:
format.json {
render json: #something , status: :created
}
I am trying to run a javascript line from my controller as a response to an AJAX call :
respond_to do |format|
if params[:return_to] == 'monthly_calendar'
render js: "alert('hey Trip!');"
else
format.js { render :partial => #task, layout: false }
format.html { redirect_to things_url }
format.json { render :json => #object.to_json }
format.xml do
if #task.new_record?
render :xml => #task.errors.to_xml
else
render :xml => #task.to_xml, :status => '201 Created'
end
end
end
Instead this returns a 406. Any ideas?
It most certainly goes to the correct call in this statement. But doesn't know what to do with the javascript call, and returns a 406.
Change it to this
respond_to do |format|
if params[:return_to] == 'monthly_calendar'
format.js { render js: "alert('hey Trip!');" }
else
.....
Because you are not specifying to what format are you responding, e.g. format.html { #your code here } when params[:return_to] == 'monthly_calendar'. Check documentation of respond_to for more information.
You can render a full view task.js.erb instead of a partial.
Here is a good tutorial on what you are trying to accomplish:
http://blog.bernatfarrero.com/jquery-and-rails-3-mini-tutorial/
I hope it helps.
Good luck.
Try respond to the js format:
format.js { render js: "alert('hey Trip!');" }
I'm getting different results if I render js versus render json .Trying to figure out why this doesn't work quite as expected
My javascript looks like this:
$( function () {
$('.delete_post').bind('ajax:success', function () {
$(this).closest('tr').fadeOut();
}
)
});
Controller:
Works
respond_to do |format|
format.js { render :nothing => true}
end
Works
respond_to do |format|
format.js { head :ok }
end
Works
respond_to do |format|
format.json { render :json => {} }
end
Doesn't work
respond_to do |format|
format.json { head :ok }
end
Doesn't work
respond_to do |format|
format.json { render :nothing => true }
end
When I examine what is happening in the ajax response I see that the cases where it doesn't work I get a "parseError".
I understand that the Content-type getting sent back is different (text/javascript vs applicaiton/json), but I would still expect the last 2 cases to work since they are sending back a 200 to the server.
(Code derived from: http://net.tutsplus.com/tutorials/javascript-ajax/using-unobtrusive-javascript-and-ajax-with-rails-3/)
format.json { head :ok }
and
format.json { render :nothing => true }
don't work because they're not returning valid json. head :ok will simply set the response header to 200 and :nothing => true will render a blank page/document which not valid json.
In our rails application we have a page where upon submit we save data in db. On this page, we have some fields which are dynamically generated and I see that in case of a validation error when page reloads it doesn't populate these fields with the values present upon posting.
In controller we have the following method defined for populating it:
def build_my_registration_type_memberships
#memberships = []
ListCache.my_registration_types.each do |my_registration_type|
#memberships << MyRegistrationTypeMembership.find_or_initialize_by_my_id_and_my_registration_type_id( #my.id, my_registration_type.id )
end end
In above method when my registration is opened in edit/view mode, it shows the values using this #membership method. But on posting in case of error it doesn't reload this with correct information. So my question is how could I repopulate #membership in case of an error on posting?
Thanks for help.
As, I understand you want some values available to your new method or the page that is rendered after if the create fails.
I assume you must have have the respond_to block in your create method. And you're doing this:
def create
...
respond_to do |format|
if #patient.save
format.html { redirect_to #object, :notice => "Object was successfully saved." }
format.xml { render :xml => #object, :status => :created, :location => #object }
else
format.html { render :action => :new }
format.xml { render :xml => #patient.errors, :status => :unprocessable_entity }
end
end
end
As you can notice, in the else part the new action is just rendered. Using some template the view is just delivered. Now, you just have to do whatever you're doing in the new action to make those values available, in the else part.
def create
...
respond_to do |format|
if #patient.save
format.html { redirect_to #object, :notice => "Object was successfully saved." }
format.xml { render :xml => #object, :status => :created, :location => #object }
else
format.html {
#memberships = []
ListCache.my_registration_types.each do |my_registration_type|
#memberships << MyRegistrationTypeMembership.find_or_initialize_by_my_id_and_my_registration_type_id( #my.id, my_registration_type.id )
end
render :action => :new
}
format.xml { render :xml => #patient.errors, :status => :unprocessable_entity }
end
end
end
And, the values you wanted will be available in the rendered form.
Better, you move to that code to a before filter or something, which makes those values available to those two methods (new and create).
Given a classic controller action. Have a look at the MARK. I need to set the status code to 200 for the response. Background: swfupload an ajax file upload solution seems to send data in a wrong format.
I tried response.headers['Status'] = 200, response.status 200, render :json => 'data', :status => 200. But the response's status code doesn't change.
def create
if params[:Filedata]
#medium = Medium.new(:swf_uploaded_data => params[:Filedata])
else
#medium = Medium.new(params[:medium])
end
respond_to do |format|
if #medium.save
format.html { redirect_to(#medium, :notice => 'Medium was successfully created.'); }
format.xml { render :xml => #medium, :status => :created, :location => #medium; }
MARK
else
format.html { render :action => "new" }
format.xml { render :xml => #medium.errors, :status => :unprocessable_entity }
end
end
end
The status code can only be declared within the return commands like render, redirect_to .... and will affect to this return command, there is no way to set the code for all the responses
For format.html { redirect_to(#medium, :notice => 'Medium was successfully created.'); } since is a redirection the code will be a 3XX and you can't change it or the redirection won't work
For format.xml { render :xml => #medium, :status => :created, :location => #medium; } you are declaring the status as created, this means for rails that the code is 201, for making it a 200 change it for:
format.xml { render :xml => #medium, :status => :ok, :location => #medium; }
What format is the AJAX call expecting in response? You're only responding to HTML and XML, so if it's expecting JavaScript or JSON, that might be a problem.
Also, I'm not sure if this matters, but I've never seen a condition inside the respond_to block like you've shown. Usually it's like this:
if #medium.save
respond_to { |format| ... }
else
respond_to { |format| ... }
end
I'm also not clear what the "MARK" is supposed to be.