Rails 4 *.json.jbuilder files ignored - ruby-on-rails

In my Rails 4.1.1 app (which has the jbuilder gem included), json views always output all columns in the table, ignoring the app/views/[model]/*.json.jbuilder files.
In routes.rb, I have:
resources :workshops do
resources :memberships
resources :events
end
In events_controller.rb, I have:
# GET /workshop/:workshop_id/events
# GET /workshop/:workshop_id/events.json
def index
#events = #workshop.events
respond_to do |format|
format.html
format.json { render json: #events }
end
end
I set the #workshop variable in a "before_action" in the controller.
When I visit /workshops/f00/events, it displays in HTML format as expected.
If I make the file, app/views/events/index.json.jbuilder:
json.events do
end
...when I visit /workshops/f00/events.json, I expect that the output would be empty. However, I get the contents of the entire #events in JSON format.
What I would like to see is only particular fields being output, given a app/views/events/index.json.jbuilder that contains:
json.array!(#events) do |event|
json.extract! event, :id, :title, :description
json.start event.starts_at
json.end event.ends_at
json.url workshop_event_url([#workshop, event], format: :json)
end
... but no matter the contents of the .jbuilder file, the output is always the same. Could anyone tell me why my .jbuilder file is being ignored, and how to get it working?

The line format.json { render json: #events } will always render the #events array since the url /workshops/f00/events accepts both html and json formats and you're rendering #events when hitting the url with the json format.
If you want to render the data in app/views/events/index.json.jbuilder change:
respond_to do |format|
format.html
format.json { render json: #events }
end
to:
respond_to do |format|
format.html
format.json
end
By not rendering the #events array you rely on Rails to output whatever is in app/views/events/index.json.jbuilder.

Related

rails render page as json

How to render page as json correctly
my chunk of code
respond_to :html, :xml, :json
def getOffersByURL
#my_model= Mymodel.where(attr1: params[:url], :validFrom => {:$lte => Time.now}).all
respond_with #my_model
end
When in trying to do like this nothing happens
http://0.0.0.0:3000/getOffersByURL?url=some_data.xml
or
http://0.0.0.0:3000/getOffersByURL?url=some_data.json
concretely it comes like this
Processing by MyController#getOffersByURL as HTML
Parameters: {"url"=>"some_data.xml"}
Try to change your function:
def getOffersByURL
#my_model= Mymodel.where(attr1: params[:url], :validFrom => {:$lte => Time.now}).all
respond_to do |format|
format.json {
render json: #my_model
}
format.html {
#my_model
}
end
end
What happens if you try to show your json like this in your view:
<%= #my_model.to_json %>
Do you have any data checking the page in the browser? Open the developers tool and try to find if the object brings any data...

dynamic rendering based on data results

I am curious if this is even possible. I am looking to render data based on the results of an action in ruby on rails. Here is the code:
def convert
render :text => Item.convert(params[:file], params[:output])
end
As you can see currently it just renders text. The item model takes in two parameters: a file and output. The output could be xml, json, plain text, etc. Some type of data. What I was hoping I could do is that I could render the output based on the output parameter. But make it dynamic. I was hoping I could do:
def convert
#items = Item.convert(params[:file], params[:output])
respond_to do |format|
format.json { render :json => #items }
format.xml { render :xml => #items }
end
end
Something that would call the method and based on the data returned it would render the appropriate data. Testing the above code returns an empty page. The body tag is completely empty.
Any ideas?
thanks
Mike Riley
If you are relying on the name of params[:output] to determine what to render, I would write is as below:
def convert
#items = Item.convert(params[:file], params[:output])
if File.extname(params[:output].match("text"))
render :text => Item.convert(params[:file], params[:output])
elsif File.extname(params[:output].match("json"))
render :json => Item.convert(params[:file], params[:output])
elsif File.extname(params[:output].match("xml"))
render :xml => Item.convert(params[:file], params[:output])
else
render :html => "default_html"
end
end
and you should have a default_html.html.erb that you would render if the extension name of the file does not match what is expected

Load XML into variable with Rails

This is how I generate XML for purchase model:
# GET /purchases/1
def show
#purchase = Purchase.find(params[:id])
#purchases = Purchase.all
respond_to do |format|
format.html # show.html.erb
format.xml { render :action => "something.xml.builder", :layout => false }
end
end
Now I'd like to get this rendered XML as string into variable so I could post it to WebService.
How can I get XML through sales_invoice.xml.builder without rendering it?
I don't want use dirty hacks and loading XML from http://appurl/purchases/1.xml
Thanks!
What I was looking for was render_to_string method.

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

Excluding some ActiveRecord properties from xml rendering in rails

I have an ActiveRecord model that I would like to convert to xml, but I do not want all the properties rendered in xml. Is there a parameter I can pass into the render method to keep a property from being rendered in xml?
Below is an example of what I am talking about.
def show
#person = Person.find(params[:id])
respond_to do |format|
format.xml { render :xml => #person }
end
end
produces the following xml
<person>
<name>Paul</name>
<age>25</age>
<phone>555.555.5555</phone>
</person>
However, I do not want the phone property to be shown. Is there some parameter in the render method that excludes properties from being rendered in xml? Kind of like the following example
def show
#person = Person.find(params[:id])
respond_to do |format|
format.xml { render :xml => #person, :exclude_attribute => :phone }
end
end
which would render the following xml
<person>
<name>Paul</name>
<age>25</age>
</person>
You can pass an array of model attribute names to the :only and :except options, so for your example it would be:
def show
#person = Person.find(params[:id])
respond_to do |format|
format.xml { render :text => #person.to_xml, :except => [:phone] }
end
end
to_xml documentation
I just was wondering this same thing, I made the change at the model level so I wouldn't have to do it in the controller, just another option if you are interested.
model
class Person < ActiveRecord::Base
def to_xml
super(:except => [:phone])
end
def to_json
super(:except => [:phone])
end
end
controller
class PeopleController < ApplicationController
# GET /people
# GET /people.xml
def index
#people = Person.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #people }
format.json { render :json => #people }
end
end
end
I set one of them up for json and xml on every object, kinda convenient when I want to filter things out of every alternative formatted response. The cool thing about this method is that even when you get a collection back, it will call this method and return the filtered results.
The "render :xml" did not work, but the to_xml did work. Below is an example
def show
#person = Person.find(params[:id])
respond_to do |format|
format.xml { render :text => #person.to_xml(:except => [:phone]) }
end
end
The except is good, but you have to remember to put it everywhere. If you're putting this in a controller, every method needs to have an except clause. I overwrite the serializable_hash method in my models to exclude what I don't want to show up. This has the benefits of not having t put it every place you're going to return as well as also applying to JSON responses.

Resources