RoR Response output type - ruby-on-rails

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 }

Related

Why is my rails controller not working?

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

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.

The action could not be found for controller

Having gone through my code I have a separate problem from my original question and rather than writing a new question. I will leave the old part at the bottom of this and post the new problem here. I do this because they are closely related.
New:
Im getting an error message saying
Unknown action
The action 'response' could not be found for CrawlerController
I'll keep it simple but the code for model, controller and routes are below in the previous question.
A basic run down is response is a def within CrawlerController as is add_Request.
The routes are matched as such:
match "/requests/new" => "crawler#add_Request"
match 'requests/:id' => 'crawler#response'
Here is controller code as per user request:
class CrawlerController < ApplicationController
def add_Request
#request = Request.new(params[:request])
respond_to do |format|
if #request.save
format.html { redirect_to(#request, :notice => 'Request was successfully created.') }
format.xml { render :xml => #request, :status => :created, :location => #request }
else
format.html { render :action => "new" }
format.xml { render :xml => #request.errors, :status => :unprocessable_entity }
end
end
end
def response
#request = Request.find(params[:id])
respond_to do |format|
format.html
format.js { render :json => #request }
end
end
def show
#request = Request.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #request }
format.json{
render :json => #request.to_json
}
end
end
end
please recheck code of controller as I can see it
class CrawlerController < ApplicationController
def add_Request
#request = Request.new(params[:request])
respond_to do |format|
if #request.save
format.html { redirect_to(#request, :notice => 'Request was successfully created.') }
format.xml { render :xml => #request, :status => :created, :location => #request }
else
format.html { render :action => "new" }
format.xml { render :xml => #request.errors, :status => :unprocessable_entity }
end
end
def response
#request = Request.find(params[:id])
respond_to do |format|
format.json {render :#request.to_json}
end
end
so one end is missing an your response action is defined inside add_Request

How to create a new object in Rails with a predefined property

I have a Rails app that has a bunch of pages, each page has many convos. On each page there's a link to create a new convo on that page. This is the code for that link:
<%= link_to 'New Convo', new_convo_path(:page=>#page) %>
However, on the next page, "convo/new" the page property is empty. What am I missing?
EDIT here are my new and create functions for convos
def new
#convo = Convo.new(params[:page])
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #convo }
end
end
# POST /convos
# POST /convos.xml
def create
#convo = Convo.new(params[:convo])
respond_to do |format|
if #convo.save
format.html { redirect_to(#convo, :notice => 'Convo was successfully created.') }
format.xml { render :xml => #convo, :status => :created, :location => #convo }
else
format.html { render :action => "new" }
format.xml { render :xml => #convo.errors, :status => :unprocessable_entity }
end
end
end
You need to load the page ... try to set a before filter ...
before_filter :find_page
private
def find_page
#page = Page.find(params[:page_id])
end
Then you build using nested resources
def new
#convo = #page.convos.build
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #convo }
end
end
def create
#convo = #page.convos.build(params[:convo])
.....
end
My guess is that you are missing a ":page=>"
def new
#convo = Convo.new(:page=>params[:page])
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #convo }
end
end

Missing templates from new Rails 3 app?

Just tried writing a simple validates_presence_of in my model, and when the errors try to render, it calls this :
Template is missing
Missing template posts/create with {:locale=>[:en, :en], :handlers=>[:builder, :rjs, :erb, :rhtml, :rxml, :haml], :formats=>[:html]} in view paths "/Users/johnsmith/Sites/shwagr/app/views"
Errors don't have seperate views in Rails3 do they? I thought that was Rails magic..
Curious if anyone had this problem, or knew how to make it correctly validate.
My Model:
validates_presence_of :category, :name, :url
My Controller:
def new
#post = Post.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #post }
end
end
def create
#post = Post.new(params[:post])
if #post.valid? && current_user.posts << #post
respond_to do |format|
if #post.save
format.html { redirect_to(#post, :notice => 'Post was successfully created.') }
format.xml { render :xml => #post, :status => :created, :location => #post }
else
format.html { render :action => "new" }
format.xml { render :xml => #post.errors, :status => :unprocessable_entity }
end
end
end
end
Update
Interesting, I 'touch app/views/posts/create.html.haml', and now it removed the error and instead loads that page instead. But why would it? Or more importantly, how can I make it just redirect back to the new_post_path(#post) like it should?
If your
if #post.valid? && current_user.posts << #post
line returns false, no render() or redirect_to() is called. Rails' default behavior then is to render the view with the same name as your method. That would be create.BUILDER.FORMAT.
Try to remove the line. Use this code instead:
#post = current_user.posts.new(params[:post])
respond_to do |format|
if #post.save
...
Or write an else case with
render :action => "new"
Ah got it. This is because it was never valid so it would loop back to itself on 'create', find no template there and error out. The correct way to set up the def create would be this
def create
#post = Post.new(params[:post])
if #post.valid? && current_user.posts << #post
respond_to do |format|
if #post.save
format.html { redirect_to(#post, :notice => 'Post was successfully created.') }
format.xml { render :xml => #post, :status => :created, :location => #post }
else
format.html { redirect_to new_user_post_path(:current) }
format.xml { render :xml => #post.errors, :status => :unprocessable_entity }
end
end
else
render :action => 'new'
end
end
No, they don't have seperate views. So do you have a app/views/posts/create.html.erb file?

Resources