How to render json with JBuilder in Rails 3.2 - ruby-on-rails

I'm trying to integrate JBuilder into Rails 3.2 project. I've installed the gem, and I've written a JBuilder file at app/views/books/index.json.jbuilder.
Here's my index action:
def index
#books = Book.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #books }
end
end
This seems to call the default as_json method of Book to render the response. What do I need to change to tell Rails to use my JBuilder template instead?

Remove the block you're passing to format.json. You're causing it to ignore your jbuilder file and instead return the result of json: #books as a response. If you leave the block out:
respond_to do |format|
format.html # index.html.erb
format.json # no block here
end
Then Rails will fall back to its default handling of the response and look for a template in your view directory, it'll find the jbuilder file and render that as the response.

Related

Rails - Purpose of using respond_to if templates are available?

I have seen some people using code like this
respond_to do |format|
format.html
format.js
end
What is the purpose of this if we have template.html and template.js. Either can be rendered without specifying respond_to
Your snippet doesn't do anything special, but the formatting options allow you to provide additional custom behavior if it is necessary.
For example, if you want to render your #products as a JSON:
respond_to do |format|
format.html
format.js { render :json => #products }
end
This is just one of the many things you can do with the format blocks. For more information, see Ruby on Rails Guides: Layouts and Rendering
The format options can take a block so that you can do some custom rendering such as rendering a file or :head response. Have a look at some of the examples here
If you don't specify different behavior for the different formats there is no reason to use respond_to. If you have templates they will automatically be picked up by rails. The respond_to method is useful if you need different behavior per format:
respond_to do |format|
format.html { render :edit }
format.json { render :json => '{}' }
end

How to create a conditional statement in the controller to detect format?

In a Rails 3.2 app, when I call a non-html format on a class - e.g. json, csv, etc - I get an error
Template is missing
Missing partial /path/to/template with {:locale=>[:en], :formats=>[:json].....
The template is called from a method in the controller.
How can I create a conditional statement in the controller that does something like:
if format is html
my_method_that_causes_the_error
end
Thanks
respond_to do |format|
format.html { my_method_that_causes_the_error }
format.csv { render :something }
end
In your controller
def index # or other method
...
respond_to do |format|
format.html # render index.html.erb
format.json { render json: ...} # one-line block
format.xml do
# multi-line block
end
end
end
Is maybe this what your are looking for?

Rails 3.1: Jbuilder rendering empty views

Trying to use Jbuilder to create some JSON views for my app, but the views are coming out empty. Using the builder code in the console, however, works just fine.
Controller code:
#placements = Placement.all
respond_to do |format|
format.html
format.json
end
Jbuilder view (index.json.builder):
Jbuilder.encode do |json|
json.array!(#placements) do |json, placement|
json.id placement.id
json.name placement.name
end
end
Visiting http://localhost:3000/placements.json results in an empty page. Removing the respond_to format block doesn't help. If I use the following code in my controller, I get an output, but it's obviously not the Jbuilder output.
respond_to do |format|
format.html
format.json {render json: #placements}
end
Has anyone else seen this problem?
#Robin - It was rendering the wrong template, but I had the wrong extension. I was using builder instead of jbuilder.
I think you need to remove f
respond_to do |format|
format.html
format.json {render json: #placements}
end
Same issue in rails specs with jbuilder 2.6.0 rails 5.0.0 and existed views.
Suggested in mentioned issue solutions:
Solved by adding render type with collection or resource
for example for index action replace:
render :index
with:
render :index, json: #collection
Or solved by configuring rspec like this:
# spec/spec_helper.rb
RSpec.configure do |config|
config.render_views = true
end
Or
class ApplicationController < ActionController::API
include ActionView::Rendering
end

Rails 3 render partial

My setup: Rails 3.0.9, Ruby 1.9.2, jQuery 1.6.2
I'm making an AJAX call from jQuery to my Rails app to this controller
class ProjectsController
def data
#project = ....
respond_to do |format|
format.html
end
end
end
For the data action, I need to render a partial file in the views\projects\_property.html.erb. What's the syntax for format.html? I tried a variety of ways but couldn't find the right syntax.
For ajax:
def data
#project = ....
respond_to do |format|
format.html
format.js
end
end
And in data.js.erb
$("#your_id").html("<%= escape_javascript( render :partial => 'property' )%>");

Add JSON support to Rails app

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

Resources