Rails how to change attribute name when rendering json? - ruby-on-rails

In my controller I have:
#pakkes = Pakke.where("navn like ?", "%#{params[:q]}%")
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #pakkes }
format.json { render :json => #pakkes.map(&:attributes) }
end
How do I change the attribute navn to name when rendering JSON?

You can do this with a one-line method in Pakke:
def as_json(*args)
super.tap { |hash| hash["name"] = hash.delete "navn" }
end
Calling super will generate json hash as usual, then before it's returned you'll swoop in and change the key of the "navn" entry.

Override the as_json method. It's used by to_json in order to produce the output. You can do something like:
def as_json options={}
{
name: navn,
.... # other attributes you want to add to json
}
end

Related

Add Virtual attribute to active record object to output

I have a custom method in my model called "file_url(:thumb)" to receive a specific thumbnail file URL. The method is provided by the carrierwave gem.
It is not stored in my database. How can I add this virtual attribute to #document so when I convert to json it's included?
module Api
module V1
class DocumentsController < ApiController
respond_to :json
def show
#document = Document.find(params[:id])
respond_to do |format|
format.json { render json: #document }
format.xml { render xml: #document }
end
end
end
end
end
You would need to define your own as_json method in the Document model. Something like this would do the trick:
def as_json(options = { })
h = super(options)
h[:thumb_url] = file_url(:thumb)
h
end

Rails - How to render json with extra field in index controller method

I'm using Rails 4.0.2 with paperclip for image upload in my project. Also I need to send a full image path of paperclip. So I can do it with add new field and set image path manually in my show controller method for particular record.
show
def show
respond_to do |format|
format.html
format.json { :json => JSON::parse(#demo.to_json.merge("new_field" => #demo.image_url.url).to_json}
end
end
When I view Json for any of my record, this is will showing good.
{
id: "1",
name: "demo",
new_field: "/demo/1/original/file.jpg"
}
In same scenario, I need to get the full image path of paperclip image for all records when I am requesting to index method on controller
index
def index
#demos = Demo.all
respond_to do |format|
format.html
format.json { :json => Demo.all.to_json}
end
end
I tried some of codes, but I don't know how exactly to write
def index
#demos = Demo.all
#demos.each do |demo|
new_field = {"new_field" => #demo.image_url.url}
# After I stucked with logic, how to uppend with 'demo'.
end
respond_to do |format|
format.html
format.json { :json => Demo.all.to_json}
end
end
How do I iterate my individual Demo model and How to merge full image path into each record.
I found the solution for my question,
def index
#demos = Demo.all
#demos_data = []
#demos.each do |demo|
new_field = {"new_field" => #demo.new_field.url}
demo = JSON::parse(demo.to_json).merge(new_field)
#demos_data << demo
end
respond_to do |format|
format.html
format.json { :json => #demos_data}
end
end
I suggest you to use two approaches, 1)use active model serializer to expose json response. 2) use jbuilder library to expose custom fields. Still you need help please let me know.
Try this:-
def index
#demos = Demo.all
#demos_data = []
#demos.each do |demo|
demo["new_field"] = #demo.image_url.url
#demos_data << demo
end
respond_to do |format|
format.html
format.json { :json => #demos_data}
end
end
maybe you can try:
def index
#demos = Demo.all
#demos.map do |demo|
new_field = {"new_field" => #demo.image_url.url}
demo.attributes.merge(new_field)
end
respond_to do |format|
format.html
format.json { :json => #demos}
end
end
attributes method returns a hash of all the object attributes, just need merge new key-value into the returned hash.
Another way of doing it is in your controller where you are rendering the json
render json: #merchants,
include: {
offers: {
except: [:created_at, :updated_at],
include: {
categories: {
except: [:created_at, :updated_at]
}
}
},
location: {
methods: :country_name,
except: [:created_at, :updated_at]
}
},
except: [:created_at, :updated_at]
Note the methods: :country_name, there you can render methods from your model as json attributes. and through include: ... you can eager load and render related models.

Rails how to render JSON as UTF-8?

In my controller I have:
def index
#title = 'asdsadas'
#kategoris = Tag.where("name like ?", "%#{params[:q]}%")
respond_to do |format|
format.html
format.json { render :json => #kategoris.map(&:attributes) }
end
end
I created a monkey patch as the answer to this question:
JSON encoding wrongly escaped (Rails 3, Ruby 1.9.2)
But the JSON has still not the correct encoding example:
Delta i t��vlingar f��r biljetter
I am pretty sure that you could fix this with your database but the quick fix may be:
new_kategoris = #kategoris.map {|v| v.force_encoding('UTF-8') }
format.json { render :json => new_kategoris.map(&:attributes) }

How do you render hashes as JSON in Rails 3

I found how to render ActiveRecord objects in Rails 3, however I cannot figure out how to render any custom objects. I am writing an app without ActiveRecord. I tried doing something like this:
class AppController < ApplicationController
respond_to :json
...
def start
app.start
format.json { render :json => {'ok'=>true} }
end
end
When you specify a respond_to, then in your actions you would make a matching respond_with:
class AppControlls < ApplicationController
respond_to :json
def index
hash = { :ok => true }
respond_with(hash)
end
end
It looks like you're conflating the old respond_to do |format| style blocks with the new respond_to, respond_with syntax. This edgerails.info post explains it nicely.
class AppController < ApplicationController
respond_to :json
def index
hash = { :ok => true }
respond_with(hash.as_json)
end
end
You should never use to_json to create a representation, only to consume the representation.
format.json { render json: { ok: true } } should work
This was very close. However, it does not automatically convert the hash to json. This was the final result:
class AppControlls < ApplicationController
respond_to :json
def start
app.start
respond_with( { :ok => true }.to_json )
end
end
Thanks for the help.
For those getting a NoMethodError, try this:
class AppController < ApplicationController
respond_to :json
...
def start
app.start
render json: { :ok => true }
end
end

How to convert records including 'include' associations to JSON

If I do something like:
result = Appointment.find( :all, :include => :staff )
logger.debug { result.inspect }
then it only prints out the Appointment data, and not the associated staff data.
If I do result[0].staff.inpsect then I get the staff data of course.
The problem is I want to return this to AJAX as JSON, including the staff rows. How do I force it to include the staff rows, or do I have to loop through and create something manually?
:include is an argument for to_json, not find. What you need to do in your controller is this:
def return_json
#appointment = Appointment.find(:all)
respond_to { |format|
format.json { render :json => #appointment.to_json(:include => :staff) }
}
end
You need to setup an association between Appointment and Staff for this to work.
Check out ActiveRecord::Serialization and ActionController::Base (see section: "Rendering JSON")
def show
#appointment = Appointment.find(:all, :include => :staff)
respond_to do |format|
format.html
format.js { render :json => #appointment.to_json(:methods => [:staff]) }
end
end

Resources