Add a single attribute to a model's Json - ruby-on-rails

I have the following code in one of my controllers;
render :json => Article.order("ID Desc").limit(3)
Which outputs an array of articles like:
[{"id":1, "content":"Blah"},{"id":2, "content":"Blah"}, {"id":3, "content":"Blah"}]
All I want to do is add a count attribute to each model. So it would be something like:
[{"id":1, "content":"Blah", "count":3},{"id":2, "content":"Blah", "count":1}, {"id":3, "content":"Blah", "count":6}]
Is there anyway to go about this in my controller without overriding the as_json method?
I saw a merge method called in another question, so I tried this:
render :json => Article.order("ID Desc").limit(3).merge(:count => 2)
with no luck.

It's better for you to handle this json yourself, but not to_json method( of Arrays or active_record)
articles = Article.order("ID Desc").limit(3)
render :json => articles.map { |article|
{
:id => article.id,
:content => article.content,
:count => 3 # or 2 or 1
}
}

Related

problem using 'as_json' in my model and 'render :json' => in my controller (rails)

I am trying to create a unique json data structure, and I have run into a problem that I can't seem to figure out.
In my controller, I am doing:
favorite_ids = Favorites.all.map(&:photo_id)
data = { :albums => PhotoAlbum.all.to_json,
:photos => Photo.all.to_json(:favorite => lambda {|photo| favorite_ids.include?(photo.id)}) }
render :json => data
and in my model:
def as_json(options = {})
{ :name => self.name,
:favorite => options[:favorite].is_a?(Proc) ? options[:favorite].call(self) : options[:favorite] }
end
The problem is, rails encodes the values of 'photos' & 'albums' (in my data hash) as JSON twice, and this breaks everything... The only way I could get this to work is if I call 'as_json' instead of 'to_json':
data = { :albums => PhotoAlbum.all.as_json,
:photos => Photo.all.as_json(:favorite => lambda {|photo| favorite_ids.include?(photo.id)}) }
However, when I do this, my :favorite => lambda option no longer makes it into the model's as_json method.......... So, I either need a way to tell 'render :json' not to encode the values of the hash so I can use 'to_json' on the values myself, or I need a way to get the parameters passed into 'as_json' to actually show up there.......
I hope someone here can help... Thanks!
Ok I gave up... I solved this problem by adding my own array methods to handle performing the operations on collections.
class Array
def to_json_objects(*args)
self.map do |item|
item.respond_to?(:to_json_object) ? item.to_json_object(*args) : item
end
end
end
class Asset < ActiveRecord::Base
def to_json_object(options = {})
{:id => self.id,
:name => self.name,
:is_favorite => options[:favorite].is_a?(Proc) ? options[:favorite].call(self) : !!options[:favorite] }
end
end
class AssetsController < ApplicationController
def index
#favorite_ids = current_user.favorites.map(&:asset_id)
render :json => {:videos => Videos.all.to_json_objects(:favorite => lambda {|v| #favorite_ids.include?(v.id)}),
:photos => Photo.all.to_json_objects(:favorite => lambda {|p| #favorite_ids.include?(p.id)}) }
end
end
I think running this line of code
render :json => {:key => "value"}
is equal to
render :text => {:key => "value"}.to_json
In other words, don't use both to_json and :json.

Rails: How can I render multiple objects to JSON?

I am trying to render multiple objects as JSON. This is my render call:
render :json => {:widget => #widget.to_json(:include => :foo),
:updated => Time.now.to_i}
I have to use to_json because of the include, and the addition updated so I know when the last call was made. The problem is that the to_json is rendered as a String instead of the object structure of the widget.
How do I get the full object structure of the widget and the updated information?
Move the :include => :foo into your Widget model.
class Widget < ActiveRecord::Base
def as_json(options = {})
super options.merge(:include => :foo)
end
end

Conditional JSON output for ActiveRecord Model (Rails 3)

I am using ActiveRecord's as_json integration with ActiveSupport::JSON to render custom output in my controllers. A basic setup I have in my model looks something like this:
def as_json(options = {})
{ :guid => id,
:title => title,
:body => body,
:date => created_at }
end
I want to take this setup a step further and show select information depending upon options passed. My question is, when I call respond_with #model_instance or render :json => #model_instance am I able to pass options that the options argument in as_json receives? If not, should I just create and convert a unique hash in my controller?
Seems like you could just call .as_json and pass in the options, no?
render :json => #mymodel.as_json(:someoption =>" value")

Rails InheritedResources - respond_with JSON, using `find_and_return_for_some_grid` instead of `find(:all)`?

I have a model, say User. I want to call /users (users_controller#index) and pass it basically a scope so it returns data based on:
The format (js, json, html)
The chart/grid/layout it will be rendered in (highcharts, basic html table, jquery flexigrid, etc.)
With inherited_resources and has_scope, you can do something like that but it's not quite it.
I want to return [{:page => 10, :cells => [{:name => "User A"}...]}] if params are something like {:action => "index", :format => "js", :grid => "flexigrid"}, and return [#<User name='User A'>...] rendered in a haml template if it's just html.
How do I do that RESTfully in Rails with inherited resources?
Something like this:
class UsersController < InheritedResources::Base
respond_with :js, :method => :find_and_return_for_grid
end
Does this require me creating my own Responder?
You need to override the index method, something like:
def index
index! do |format|
format.html
format.js do
if(params[:grid] == "flexigrid")
render :json => format_for_grid(collection).to_json
end
end
end
end
With format_for_grid a method that convert an array of Users to the data format you want
Personaly speaking I won't format the js response like this, I mean splitting the response in cells is something I would do on view side with js, beacause has to do with the way you want to display the data, I think it would taste more Restful to just return the non display-oriented collection.to_json

Ruby on rails: Render 2 partials or figure out the kind of class and object is

I want to display different types of objects in the same ajax called controller function. I want to render out when I send back an ajax call. The problem is I want the "title" attribute of one object and the "name" attribute of another object. I can't render 2 partials and can seem to figure out how to check the type of object an object is. How do I solve this problem?
Here is my current controller setup (NOT CORRECT)
#objects = Obj.find(:all,:conditions => ["name Like ?", "#{prefix}%"])
#moreObjects = ObjTwo.find(:all,:conditions => ["title Like ?","#{prefix}%"])
if #objects.empty?
render :text => "No Matches"
else
render :partial => 'one', :collection => #objects
end
if #moreObjects.empty?
render :text => "No Matches"
else
render :partial => 'two', :collection => #moreObjects
end
try something like
<%= obj.title if obj.respond_to?(:title) %>
Here's one option that doesn't involve checking its type - in your Obj and ObjTwo classes add a new method:
def fancy_pants
title
end
def fancy_pants
name
end
Then you can combine #objects and #moreObjects - you'll only need one if statement and one partial.
#search_domination = #objects + #moreObjects
if #search_domination.empty?
render :text => "No Matches"
else
render :partial => 'one', :collection => #search_domination
end
You could use Object.is_a? but that's not a very clean solution. You could also try mapping your data before presentation to help keep your views lightweight.

Resources