Loop to create JSON object - ruby-on-rails

just trying to loop thru my Story model.. and create JSON object and insert it into Call and send it.. But i'm not sure how to loop thru Stories..
I've done this:
#stories = Array.new
Story.where(newsletter_id: current_user.selected_newsletter) do |story|
#stories << {
:title => story.title,
:image_url => story.image_url
}
end
and i'm trying ti insert the loop to this JSON OBJECT
"message" => {
"attachment" => {
"type" => "template",
"payload" => {
"template_type" => "generic",
"elements" => [{this is the array}]
}
}
}
The array with multiple stories should looks like this:
[
{
"title" => "title....1",
"image" => "image....1"
},
{
"title" => "title....2",
"image" => "image....3"
}
....
]

Try the following:
#stories = Story.where(newsletter_id: current_user.selected_newsletter)
.select(:title, 'image_url as image').as_json(except: :id)
And then:
{
"message" => {
"attachment" => {
"type" => "template",
"payload" => {
"template_type" => "generic",
"elements" => #stories
}
}
}
}

Related

add two parameters in Soulmate::Loader

i have two fields in my model and i want add them in Soulmate::Loader:
for example, my "person" model has name and email field. and i want load then in Soulmate:
loader = Soulmate::Loader.new("people")
loader.add("term" => name, "id" => self.id, "data" => {
"link" => Rails.application.routes.url_helpers.person_path(self)
})
i want add name and email in loader.add. but i can't.
def load_into_soulmate
loader = Soulmate::Loader.new("people")
loader.add("term" =>{ name , email }, "id" => self.id, "data" => {
"link" => Rails.application.routes.url_helpers.person_path(self)
})
end
and
def load_into_soulmate
loader = Soulmate::Loader.new("people")
loader.add("term" =>{ "name" => name ,"email" => email }, "id" => self.id, "data" => {
"link" => Rails.application.routes.url_helpers.person_path(self)
})
end
error show when i use Person.find_each(&:save) for add datas to redis:
ArgumentError: ArgumentError
from /var/lib/gems/2.2.0/gems/soulmate-1.1.0/lib/soulmate/loader.rb:31:in `add'
but all is wrong.
I think you have to use aliases.
def load_into_soulmate
loader = Soulmate::Loader.new("people")
loader.add("term" =>"name", "id" => self.id, "aliases" => [email], "data" => {
"link" => Rails.application.routes.url_helpers.person_path(self)
})
end

What is an elegant way of modifying hashes inside an array within a nested hash in Ruby

I would like to transform this
def some_process(k,v)
return "#{v}_#{k}"
end
a_hash = {
"i_love_hashes" => {
"thing" => 20,
"other_thing" => "0",
"yet_another_thing" => "i disagree",
"_peculiar_thing" => [
{"count" => 30,
"name" => "freddie"},
{"count" => 15,
"name" => "johhno"},
{"count" => 12,
"name" => "mohammed"},
]
},
"as_do_i" => {
"thing" => 10,
"other_thing" => "2",
"yet_another_thing" => "i strongly agree",
"_peculiar_thing" => [
{"count" => 10,
"name" => "frodo"},
{"count" => 4,
"name" => "bilbo"},
{"count" => 2,
"name" => "elizabeth"},
]
}
}
into this
{
"i_love_hashes"=>{
"thing"=>20,
"other_thing"=>"0",
"yet_another_thing"=>"i disagree",
"_peculiar_thing"=> [
{"count"=>30, "name"=>"freddie", :sinister_name=>"freddie_i_love_hashes"},
{"count"=>15, "name"=>"johhno", :sinister_name=>"johhno_i_love_hashes"},
{"count"=>12, "name"=>"mohammed", :sinister_name=>"mohammed_i_love_hashes"}
]},
"as_do_i"=>{
"thing"=>10,
"other_thing"=>"2",
"yet_another_thing"=>"i strongly agree",
"_peculiar_thing"=>[
{"count"=>10, "name"=>"frodo", :sinister_name=>"frodo_as_do_i"},
{"count"=>4, "name"=>"bilbo", :sinister_name=>"bilbo_as_do_i"},
{"count"=>2, "name"=>"elizabeth", :sinister_name=>"elizabeth_as_do_i"}
]
}
}
this is the code I am currently using to achieve this
a_hash.each_with_object({}) do |(k,v),o|
o.merge!({k =>
v.each_with_object({}) do |(a,b),g|
g.merge!({ a =>
(b.is_a?(Array) ? b.collect {|x| x.merge({sinister_name: (some_process k, x["name"])})} : b)
})
end
})
end
Ignoring the specific details of what is being returned by "some_process" (what is important is that it depends on the outer most key and the inner name values, in this example), are there any alternatives that would be considered more elegant?
Why not do a recursive function?
def add_siniter(hash)
hash[:siniter_name] = "#{hash['name']}_i_love_hashes"
hash
end
def format_hash(item)
case item
when Hash then item.keys.each{|key| format_hash(item[key])}
when Array then item.map!{|h| add_siniter(h)}
end
end
format_hash(a_hash)

How to send custom parameter from jqgrid to rails controller?

I use jqgrid in my rails to show data in my web
and I want to decide which data to show depends on which page the user is surfing
here's the code
show.html.erb
<%=raw jqgrid("people_list", "people", "/people",
[ { :field => "pid", :label => "pid" ,:editable => true},
{ :field => "name", :label => "name" ,:editable => true},
{ :field => "gender", :label => "gender" ,:editable => true},
{ :field => "birthday", :label => "birthday" ,:editable => true}
] ,
{:autowidth=>true,:add => true,:edit => true,:delete => true,:view => true,:edit_url => post_data_people_url,:sortable_rows => 'true'
}
)%>
people_controller.rb
def index
index_columns ||= [:pid,:name,:gender,:birthday,:school]
current_page = params[:page] ? params[:page].to_i : 1
rows_per_page = params[:rows] ? params[:rows].to_i : 10
conditions={:page => current_page, :per_page => rows_per_page}
conditions[:order] = params["sidx"] + " " + params["sord"] unless (params[:sidx].blank? || params[:sord].blank?)
if params[:_search] == "true"
conditions[:conditions]=filter_by_conditions(index_columns)
end
#temp = Person.limit(0).all
KlassesPeople.where(:klass_id => 1).each do |stu|########
#temp.concat( Person.where(:id => stu.person_id) )
end
#people = #temp.paginate(conditions)
total_entries=#people.total_entries
respond_with(#people) do |format|
format.html
format.json { render :json => #people.to_jqgrid_json(index_columns, current_page, rows_per_page, total_entries)}
end
end
I want to pass the value of klass id from the jqgrid to the controller to determine the value of klass_id in the line with "########"
any idea?
I don't know how to format the code for you but you can use the postData parameter to pass a value to your controler every time the jqGrid would get data.
postData: { KeyName: KeyValue },
If you need to set this value dynamically you can set it via something like:
$('#gridName').jqGrid('setGridParam', { postData: { KeyName: KeyValue });

Ruby how to sort hash of hashes?

I have that deep Hash of hashes:
my_hash = {
:category_1 => {
:solution_1 => { :order => 1 },
:solution_2 => { :order => 2 }
},
:category_2 => {
:solution_3 => { :order => 3 },
:solution_4 => { :order => 4 }
}
}
I want to sort :solution_* hashes under :category_* hashes by key :order. Any suggestions?
(fixed)
Let's say you have the following hash of people to ages:
people = {
:fred => { :name => "Fred", :age => 23 },
:joan => { :name => "Joan", :age => 18 },
:pete => { :name => "Pete", :age => 54 }
}
use sort_by to get where we want to go:
people.sort_by { |k, v| v[:age] }
# => [[:joan, {:name=>"Joan", :age=>18}],
[:fred, {:name=>"Fred", :age=>23}],
[:pete, {:name=>"Pete", :age=>54}]]
Ok, you didn't specify your question, so I'm assuming you want one layer removed. I changed the starting hash a bit to actually see if the sorting works:
my_hash = {
:category_1 => {
:solution_1 => { :order => 2 },
:solution_2 => { :order => 3 }
},
:category_2 => {
:solution_3 => { :order => 4 },
:solution_4 => { :order => 1 }
}
}
Hash[my_hash.inject({}) { |h, (k, v)| h.merge(v) }.sort_by { |k,v| v[:order] }]
#=> {:solution_4=>{:order=>1}, :solution_1=>{:order=>2}, :solution_2=>{:order=>3}, :solution_3=>{:order=>4}}
EDIT:
Taking into account your clarification (and still starting from the modified unsorted hash I posted above):
sorted = my_hash.inject({}) do |h, (k, v)|
h[k] = Hash[v.sort_by { |k1, v1| v1[:order] }]
h
end
#=> {:category_1=>{:solution_1=>{:order=>2}, :solution_2=>{:order=>3}}, :category_2=>{:solution_4=>{:order=>1}, :solution_3=>{:order=>4}}}

How to "trasform" an array of hash so that you can customize logic to access its data?

I am using Ruby on Rails 3 and I would like to "trasform" the following array so that I can use my custom logic to access its data.
This is the original array from which I have to build a new one
[
{
"account" => {
"id" => 45,
"name" => "Test_name",
"..." => ..."
}
},
{
"other" => {
"sub_other" => {...}
}
}
]
I would like to trasform the above array so that I can do in my controller something like
array_name[45]
# => {
"name" => "Test_name",
"..." => ..."
}
but only for the account hashs. The other hash should remain untouched.
How can I proceed to build the new array?
If I understand your requirements correctly, I think you are better off constructing a hash from account id to account data. Perhaps something like this will work:
arr = [
{
"account" => {
"id" => 45,
"name" => "Test_name",
"..." => "..."
}
},
{
"other" => {
"sub_other" => "..."
}
}
]
account_hashes = arr.select {|item| item.keys.first == "account"}
answer = account_hashes.inject({}) do |acc, item|
acc[item["account"].delete("id")] = item["account"]
acc
end

Resources