Rails Json response help - ruby-on-rails

In my controller i have:
#photo = Photo.find(:all)
respond_to do |format|
...
format.json { render :json => #photo.to_json)
end
so my response looks like:
{
"photo":
{
"updated_at":"2010-10-14T19:12:35Z",
"photo_file_size":206422,
"created_at":"2010-10-14T19:12:01Z"
}
},
{
"photo":
{
"updated_at":"2010-10-16T18:19:38Z",
"photo_file_size":83593,
"created_at":"2010-10-14T19:14:35Z"
}
}
how can i add an additional json key value pair for every photo block?
something like:
"photo":
{
"updated_at":"2010-10-14T19:12:35Z",
"photo_file_size":206422,
"created_at":"2010-10-14T19:12:01Z"
----> "created_at_b":"2010/10/14"
}
maybe :include option?
thanks!

to_json can be made to include the result of any method available on your model. For example you could add the following method to your model:
class Photo < ActiveRecord::Base
def created_at_b
# whatever you want to do
end
end
In your controller you add:
format.json { render :json => #photo.to_json(:methods=>[:created_at_b])
That should return the json that you're after.

Related

How to render a jsonapi-resources response in an custom controller action?

I have implemented my own object creation logic by overriding the create action in a JSONAPI::ResourceController controller.
After successful creation, I want to render the created object representation.
How to render this automatically generated JSON API response, using the jsonapi-resources gem?
Calling the super method does also trigger the default resource creation logic, so this does not work out for me.
class Api::V1::TransactionsController < JSONAPI::ResourceController
def create
#transaction = Transaction.create_from_api_request(request.headers, params)
# render automatic generated JSON API response (object representation)
end
end
You could do something like this:
class UsersController < JSONAPI::ResourceController
def create
user = create_user_from(request_params)
render json: serialize_user(user)
end
def serialize_user(user)
JSONAPI::ResourceSerializer
.new(UserResource)
.serialize_to_hash(UserResource.new(user, nil))
end
end
this way you will get a json response that is compliant with Jsonapi standards
render json: JSON.pretty_generate( JSON.parse #transaction )
def render_json
result =
begin
block_given? ? { success: true, data: yield } : { success: true }
rescue => e
json_error_response(e)
end
render json: result.to_json
end
def json_error_response(e)
Rails.logger.error(e.message)
response = { success: false, errors: e.message }
render json: response.to_json
end
render_json { values }

Rails Controller Modify JSON Response

I have this method in my controller:
# GET /bios/1
# GET /bios/1.json
def show
if member_session?
#member = MemberPresenter.new(#bio.member)
# I need something here to add a flag to the json response to signal this is a member session.
else
#member = MemberPresenter.new(#bio.member)
end
end
I need to modify the json response to return something like:
{ member: #member, member_session: true }
Thanks in advance!
You can use json param for render functions:
render json: { member: #member, member_session: true }
But it's not the best way to render JSON in rails. I'd recommend you try to use https://github.com/rails-api/active_model_serializers
I'm not sure if you specifically want to return json all the time but here's an alternative to rendering other formats as well:
respond_to do |format|
format.html
format.json { render json: { member: #member, flag: #member.status } }
end
For small and simple objects, doing this is fine, but if you had to drag the associations along, you have the choice of using a serializer, or you could override the to_json method to something like this.
# member.rb
def as_json(options = {})
options = options.merge(
except: [
:updated_at,
:created_at,
],
include: { # Getting associations here
address: {
only: [:street, :zip_code],
include: {
neighbors: { only: :name }
}
}
}
)
super.as_json(options)
end
And finally within the controller, render json: #member.to_json and it will pull all the associations you want with it. This is the lazy man's way of serializing aka what I do :)

Two different as_json methods

I'd like to have my json render in two different ways. I now have my as_json method overridden to display a full object in json form like this:
{
prop1: stuff,
prop2: stuff,
innerthings: {
{
prop1:stuff,
prop2:stuff
}
{
prop1:stuff,
prop2:stuff
}
}
}
And the as_json looks like:
#Renders json
def as_json(options={})
super(
:except => [:created_at, :updated_at],
:include => [{:innerthings = > {
:except => [:created_at, :updated_at]
}}]
)
end
I'd also like to have a second option to render like this:
{
prop1:stuff,
prop2:stuff,
countinnerthings:10
}
current when the code below is used, I get the first render:
respond_to do |format|
format.json { render json: #thing}
end
I'd also like to be able to render with something like as_list that I could use in a case like the below to render just a simple list of the objects.
respond_to do |format|
format.json { render json: #things.as_list }
end
Is there a simple way to do this in ruby on rails?
Instead of rolling your own as_json method. Take a look at ActiveModel Serializers. I think it will satisfy you use-case and help organize your code.
You can just define an as_list method
def as_list
{
prop1: "stuff"
}
end
If you need to use includes etc you can call as_json from your at_list method. As had been said serializers are a better option in general.

How to Include additional field in Rails 3 Application JSON Response

I have a Rails application which displays nested form in json format.
In the JSON Response i am also displaying an id field which represent another table.
How to display name corresponding to that id what i am getting so that i can display both name and id in my json format.
My controller
show method
def show
#maintemplate = Maintemplate.find(params[:id])
respond_with (#maintemplate) do |format|
format.json { render :json => #maintemplate }
end
end
Thanks in advance....
Try this:
render :json => #maintemplate.to_json(:include => { :user => { :only => :name } } )
This will replace the user_id key with a user key and a value with only the name attribute of user, like this:
{
"user_id": "12"
"user": { "name": "..." }
...
}
You can then access the username in the json response with ["user"]["name"]. You can also access the user id with ["user_id"].
For more see the documentation on as_json.
Update:
Using the info provided in the comments, I think this is what you actually want:
render :json => #maintemplate.to_json(:include => { :routine => { :include => :user, :user => { :only => :name } } } )
Add to as_json method with the additional method-attributes you desire to the class in which you are calling.
class MainTemplate
...
def name
User.find(self.user_id).name
end
def as_json(options = {})
options[:methods] = :name
super(options)
end
end

How can I include a model association in a JSON response in Rails?

I've looked at similar posts but can't seem to quite figure it out.
I have the following function which works just fine. The Listing model has a foreign key called price_id which maps to the Price model and its price_range column. Price_id is returned as part of the message object in the JSON response.
How can I return the corresponding price_range value from the association instead of the price_id value (as part of the message obj, and keep the other attributes)?
def update
#listing = Listing.find(params[:listing][:id])
#if params were passed in for updating
if #listing.update_attributes(params[:listing])
#should we return the whole thing or just what's needed?
json_response = {
"success" => #listing.save, #save to DB and assign true/false based on success...
"message" => #listing.attributes #USE attributes to show output the content of the #message obj, and not another object called "message"
}
respond_to do |format|
#json response
format.html { render:json => json_response }
format.xml { render :xml => #listing }
#normal response. Consider leaving this for now?
#format.html { render :action => "detail" } #refresh this page, with new data in it. Consider trying to use redirect instead?
#format.xml { head :ok }
end
end #end if
end
add a method in your Listing model with the price_range and call it in serializable_hash
class Listing
def price_range
price.price_range
end
end
Like explain on comment you can use delegate instead this method :
class Listing
delegate :prince_range, :to => price
end
In you controller you can now do :
json_response = {
"success" => #listing.save, #save to DB and assign true/false based on success...
"message" => #listing.serializable_hash(:methods => [:price_range])
}
Based on what I read in this article, you should be able to do this:
class Listing
def as_json
super(:include => :price)
end
end
Then in your controller:
json_response = {
"success" => #listing.save,
"message" => #listing.as_json
}
If I understand correctly, you want to add #listing.price.price_range value to the "message" ?
If so, try this:
"message" => #listing.attributes[:price_range] = #listing.price.price_range

Resources