Rails - Building a JSON object with multiple items - ruby-on-rails

currently I am creating a JSON object as follows:
#comments = Array.new
comments.collect do |comment|
#comments << {
:id => comment.id,
:content => html_format(comment.content),
:created_at => comment.created_at
}
end
#comments.to_json
And this returns something like this:
[{"created_at":"2011-03-02T09:17:27-08:00","content":"<p>Random.......</p>","id":734}, {"created_at":"2011-03-02T09:17:27-08:00","content":"<p>asdasd.......</p>","id":714}, {"created_at":"2011-03-01T09:17:27-08:00","content":"<p>Random.......</p>","id":134}, {"created_at":"2011-03-01T02:17:27-08:00","content":"<p>dasdasdasdasd.......</p>","id":3124}]
Problem here is that I need to include a few other items that aren't arrays. What I would like is the JSON object to look something like this:
[comments: {"created_at":"2011-03-02T09:17:27-08:00","content":"<p>Random.......</p>","id":734}, {"created_at":"2011-03-02T09:17:27-08:00","content":"<p>asdasd.......</p>","id":714}, {"created_at":"2011-03-01T09:17:27-08:00","content":"<p>Random.......</p>","id":134}, {"created_at":"2011-03-01T02:17:27-08:00","content":"<p>dasdasdasdasd.......</p>","id":3124}, last_load: "123123123123", last_view: "zxczcxzxczxc"]
Any ideas on how I can take what I have above, and expand it to pass additional items other than the comments array?
Thank you!

Add your list to a hash, and then call to_json on the hash.
> a = [1,2,3]
=> [1, 2, 3]
> h = {:comments => a, :foo => "bar"}
=> {:foo=>"bar", :comments=>[1, 2, 3]}
> h.to_json
=> "{\"foo\":\"bar\",\"comments\":[1,2,3]}"

Related

How to merge hash with activerecord relations in controller / scope

I have Item model(table) with column [id,name,notes]. then I have hash lets call it stock with column [id_of_item,total_stock],
when I do query in controller I would like to join the hash into the table as additional column so I can show the total_stock of the item.
I prefer not to use map/each (looping through all the items since the items table has thousand records. I still don't know whether this possibly or not, thank you.
if your stock is
[[1, "total_stock_1"], [2, "total_stock_2"]]
you should use
stock = Hash[[[1, "total_stock_1"], [2, "total_stock_2"]]]
to translate your hash to this style
stock = {1 => "total_stock_1", 2 => "total_stock_2"}
stock = {1 => "total_stock_1", 2 => "total_stock_2"}
#items = Item.all.map{|item| item.attributes.merge({total_stock: stock[item.id]})}
# the output will be a json not a ActiveRecordRelation
[
{:id => 1, :name => 'item1', :notes => xxx, :total_stock => "total_stock_1"},
{:id => 2, :name => 'item2', :notes => yyy, :total_stock => "total_stock_2"}
]
You can do this in controller:
#items = Item.all
render json: #items.map{|item| {'item': item.as_json.merge stock.select{|item| item['id_of_item'] == item.id}['total_stock']} }}

How can I use bulk insert in the case

how can I use bulk insert from array in Rails, like below:
name_list = [{"id" => 1,"name" => "bob"},{"id" => 2,"name" => "ted"}]
Namelist.import name_list
I can`t insert values of above array.
You can do that in single insert query using activerecord-import gem.
name_list = [{"id" => 1,"name" => "bob"},{"id" => 2,"name" => "ted"}]
namelist_objects = []
name_list.each do |n|
namelist_objects << Namelist.new(n)
end
Namelist.import(namelist_objects)
The above answers of others will work fine but name_list.size number of insert queries will run which is not feasible when the array is big.
Hope that helps!
You can just pass the array of hash to create
Namelist.create([{id: 1, name: "bob"}, {id: 2, name: "ted"}])
I am not sure what you want, but maybe it will help you. I think you want create Namelist for both name_lists, isn't ?
name_list = [{"id" => 1,"name" => "bob"},{"id" => 2,"name" => "ted"}]
name_list.map{|k| Namelist.create(k) }

Search ignoring certain blank parameters

I have a simple search action that has 3 parameters and a where method to search a model. If I search and some of the parameters are nil, it will not return the records I want. I want it to search the database by only using the parameters that are not nil/blank. So if only one category is entered and sent in the parameters, I want my controller to ignore the other two parameters. However, if the other parameters are present, I want them to be included in the search.
I've tried many approaches but I can't get it to work properly. Here's my code.
hash = []
cat = :category_id => params[:category_id]
col = :color_id => params[:color_id]
brand = :brand_id => params[:brand_id]
if params[:category_id].present?
hash += cat
end
if params[:color_id].present?
hash += col
end
if params[:brand_id].present?
hash += brand
end
#results = Piece.where(hash).preload(:item).preload(:user).group(:item_id).paginate(:page => params[:page], :per_page => 9)
I've put the variables into strings and hashs, called to_a, joined them with (","). Nothing works.
Thanks
Try this code.
criteria = { :category_id => params[:category_id], :color_id => params[:color_id],
:brand_id => params[:brand_id] }.select { |key,value| value.present? }
#results = Piece.where(criteria).preload(:item).preload(:user).group(:item_id).
paginate(:page => params[:page], :per_page => 9)

How to output an Array as JSON?

I have the following:
#array.inspect
["x1", "x2", "adad"]
I would like to be able to format that to:
client.send_message(s, m, {:id => "x1", :id => "x2", :id => "adad" })
client.send_message(s, m, ???????)
How can I have the #array output in the ??????? space as a ids?
Thanks
{:id => "x1", :id => "x2", :id => "adad" } is not a valid hash since you have a key collision
it should look like:
{
"ids": ["x1", "x2", "x3"]
}
Update:
#a = ["x1", "x2", "adad"]
#b = #a.map { |e| {:id => e} }
Then you can do b.to_json, assuming you have done require "json" already
Well ordinarily you could do something like this:
Hash[#array.collect{|i| [:id, i]}]
But that will result in {:id => "adad"} because the first element will punch all the rest: hashes in ruby have unique keys. So I don't think there's a super awesome way to do this offhand.

Assigning array name to a variable and sorting in RoR

Absolute RoR newbie here, I'm trying to render out multiple leagues in a loop, incrementing the div_# each time, here's a cut down version, without the html. It works when I hard code div_1 or div_2 to be sorted, but div_name doesn't work, even though it has the right contents I need it to be seen as the array.
<% div_1 = Array.new
div_1 << { :Name => 'Rob', :Played => '2', :Won => '1', :Lost => 1, :Points => 4}
div_2 = Array.new
div_2 << { :Name => 'Gavin', :Played => '2', :Won => '1', :Lost => 1, :Points => 4}
for i in (1..2)
i = i.to_s
div_name = "div_" + i
div_name.sort_by { |position| position[:Points] }.reverse!.each do |position| %>
<%= position[:Name] %>
There are lots of problems here:
div_1 = Array.new
div_1 << { :Name => 'Rob', :Played => '2', :Won => '1', :Lost => 1, :Points => 4}
div_1 is now an array with a single element, which is a hash. You don't need an array if you'll just have one element in it.
for i in (1..2)
Where's the block for this loop? After that statement, i is still undefined, so when you call
i = i.to_s
you'll get a NameError.
div_name = "div_" + i
Even if i == 1, div_name will be a string with value 'div_1', and not a copy or instance of the div_1 variable you define above.
div_name.sort_by { |position| position[:Points] }.reverse!.each do |position| %>
Now you're trying to call sort_by on a string, which doesn't respond to that, because it doesn't make sense.
<%= position[:Name] %>
You don't have a variable named position defined at this scope.
Also, when you find yourself putting lots of logic inside of a view within <% %> tags, that's a sign that you need to move that code elsewhere, like to the controller. You could define and calculate #positions as an array of hashes in the controller, and then in the view do something like:
<% #positions.each do |position| %>
<%= position[:name] %>
<% end %>

Resources