Why is my rails controller not working? - ruby-on-rails

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!');" }

Related

how to debug a POST 500 internal server error

I'm trying to set up jquery file upload on a Rails 3.2 app, following this guide.
Everything is almost working perfectly but, when I click "start upload" I see an error in Chrome's console:
POST http://testapp.dev/photos 500 (Internal Server Error)
In the log I'm getting:
ActionView::MissingTemplate (Missing template photos/create, application/create with {:locale=>[:en], :formats=>[:js, :html], :handlers=>[:erb, :builder, :coffee]}.
I've been through the controller with a fine tooth comb, but I can't work out what is causing this error or why its looking for a create partial. What is a systematic way to debug this?
Thanks
EDIT
My controller actions look like this:
class PhotosController < ApplicationController
def index
#photos = Photo.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #photos }
format.json { render :json => #photos.collect { |a| a.to_jq_upload }.to_json }
format.js { render :json => #photos.collect { |a| a.to_jq_upload }.to_json }
end
end
def show
#photo = Photo.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #photo }
format.json { render :json => #photo }
format.js
end
end
def new
#photo = Photo.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #photo }
format.json { render :json => #photo }
format.js
end
end
def edit
#photo = Photo.find(params[:id])
end
def create
#photo = Photo.new(params[:photo])
respond_to do |format|
if #photo.save
format.html {
render :json => [#photo.to_jq_upload].to_json,
:content_type => 'text/html',
:layout => false
}
format.json { render :json => [ #photo.to_jq_upload].to_json }
format.js
else
format.html { render :action => "new" }
format.xml { render :xml => #photo.errors, :status => :unprocessable_entity }
format.json { render :json => [ {:error => "An error was encountered while processing your photos. Please try again."}], status: 304 }
format.js
end
end
end
def update
#photo = Photo.find(params[:id])
respond_to do |format|
if #photo.update_attributes(params[:photo])
format.html { redirect_to(#photo, :notice => 'Asset was successfully updated.') }
format.xml { head :ok }
format.json { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #photo.errors, :status => :unprocessable_entity }
format.json { render json: #photo.errors, status: :unprocessable_entity }
end
end
end
# DELETE /assets/1
# DELETE /assets/1.xml
def destroy
#photo = Photo.find(params[:id])
#photo.destroy
respond_to do |format|
format.html { redirect_to(photos_url) }
format.xml { head :ok }
format.json { render :json => true }
format.js
end
end
end
It looks like the respond_to block is hitting format.js which will attempt to render a template (a default if no options are provided).
Because the jQuery-file-upload plugin you're using requires a particular JSON response, having a respond_to block seems unnecessary and you can get away with the following
def create
#photo = Photo.new(params[:photo])
if #photo.save
render :json => [ #photo.to_jq_upload].to_json
else
render :json => [{ :error => "An error was encountered while processing your photos. Please try again." }], :status => 304
end
end
I would also highly recommend the debugger gem which will allow you to set breakpoints within the application so you can better tell what is happening.
To add the debugger gem, you'll need to first add the gem to your Gemfile and run a bundle install from the command line. Next, you simply add the word debugger on the line of code you want to set the breakpoint at. In your case, you could do
def create
#photo = Photo.new(params[:photo])
debugger
if #photo.save
# ... rest of code
Finally, you'll need to restart the server with the --debugger option. When the jQuery-file-upload plugin posts the request to the server, it'll hit the breakpoint and you can better analyze the passed params as well as step through the code to get an idea of what is happening. Cheers.

Rendering json versus js in rails

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.

RoR Response output type

I want my Rails rest application has json as default output format , also I want remove html format. Any suggestions? Thanks
Yes you can do it.
In your controller,
respond_to do |format|
#format.html # show.html.erb
#format.xml { render :xml => #post }
format.json { render :json => #post }
end
or you can handle it as javascript
respond_to do |format| format.js { render :json { :only => :name}.to_json end
then you just access your action with ".js" in the end
Try like this
format.any(:xml, :html, :json) { render :json => #post }

How to manipulate response status code from a Rails Controller action

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.

Ruby on Rails' respond_to causing strange error

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.

Resources