Rails 3 : Generate view using rabl - ruby-on-rails

In my Rails Application i have Two instance variables #departments and #register
#departments =
{
"users": [
{
"departmentid": "DP11"
},
{
"departmentid": "DP12"
},
{
"departmentid": "DP13"
},
{
"departmentid": "DP10"
}
]
}
#register =
{
"attendance": [
0,
0,
2,
1
]
}
#register contains an array .
Is it possible to show like below format using rabl (attendancebydepartment.json.rabl) view
{
"users": [
{
"departmentid": "DP11",
"attendance"=0
},
{
"departmentid": "DP12",
"attendance"=0
},
{
"departmentid": "DP13",
"attendance"=2
},
{
"departmentid": "DP10",
"attendance"=1
}
]
}
My controller looks like
def attendancebydepartment
#register = Array.new
#departments = User.select('departmentid').uniq
startdate = params[:startdate]
enddate = params[:enddate]
#count = #departments.count
#departments.each do |d|
#register << (Register.where(:date => startdate..enddate , :departmentid => d.departmentid).sum(:one))+(Register.where(:date => startdate..enddate , :departmentid => d.departmentid).sum(:two))
end
end
Is it possible to add each department and its corresponding attendance to array,so that i can display like expected format.

Perhaps use the zip method to create a new variable and then present that.
irb(main):001:0> departments = {'users' => [{'id' => 1}, {'id' => 2}]}
=> {"users"=>[{"id"=>1}, {"id"=>2}]}
irb(main):002:0> register = {'attendance' => [0,1]}
=> {"attendance"=>[0, 1]}
irb(main):004:0> departments['users'].zip(register['attendance'])
=> [[{"id"=>1}, 0], [{"id"=>2}, 1]]
On the other hand, it looks like a simpler design would be to have a Department model that has a has_many association with Users. Then you could refer to the count of users directly from an instance of Department.

It may be easiest to create objects in your controller using OpenStruct, something like this, but I would recommend re-writting attendancebydepartment to not loop twice.
#users = []
#departments.each_with_index do |dep, index|
user = OpenStruct.new
user.departmentid = dep.departmentid
user.attendence = #register[index].attendence
#users << user
end
And in the view:
collection #users => :users
attribute :departmentid, :attendence

Related

Merge two hashes in ruby

I have two collections of hashes
and_filters = [{:filter=>:brand, :value=>"Fila"}, {:filter=>:brand, :value=>"Adidas"}]
or_filters = [{:filter=>:gender, :value=>"Hombre"}]
and i need make like the following struct
:_or => [
{ :_and => [
{:gender => "Hombre"},
{:brand => "Adidas"}]
},
{ :_and => [
{:gender=>"Hombre"},
{:brand=>"Fila"}]
}
]
For this i did
query[:_or] = []
or_filters.each do |or_f|
query[:_or] << {
:_and => [
and_filters.map do |and_f|
{and_f[:filter] => and_f[:value]}
end
{ or_f[:filter] => or_f[:value] }
]
}
end
but an error Expected: { shows in code. Apparently the second loop is badly syntactically
It's not pretty, but I believe this gives the desired results:
{_or: or_filters.each_with_object([]) do |or_filter, or_filter_ary|
or_filter_hsh = {or_filter[:filter] => or_filter[:value]}
and_filters.each do |and_filter|
and_filter_hsh = {and_filter[:filter] => and_filter[:value]}
or_filter_ary << {_and: [or_filter_hsh, and_filter_hsh]}
end
end
}
Which gives:
{:_or => [
{ :_and => [
{:gender=>"Hombre"},
{:brand=>"Fila"}
]},
{ :_and => [
{:gender=>"Hombre"},
{:brand=>"Adidas"}
]}
]}
It looks like you want every combination of the given and_filters with the given or_filters. In that case, and assuming you don't care about order (:gender before :brand vs. the other way around) Array#product is your friend:
result = {
_or: and_filters.product(or_filters).map do |a|
{ _and: a.map {|filter:, value:| { filter => value }} }
end
}
# => {
# :_or => [
# {:_and => [{:brand=>"Fila"}, {:gender=>"Hombre"}]},
# {:_and => [{:brand=>"Adidas"}, {:gender => "Hombre"}]}
# ]
# }
See it in action on repl.it: https://repl.it/#jrunning/HorizontalDirectCharmap
Thats what i was looking for
query = {}
query[:_or] = or_filters.map do |or_f|
and_filters_aux = and_filters.dup
and_filters_aux << or_f
{ :_and => and_filters_aux.map{|hsh| {hsh[:filter] => hsh[:value]} } }
end
https://repl.it/repls/ShyLateClients

How to chaange my as_json method?

Now i have used the as_json method like this in my model
def as_json(options = {})
{
id: id,
diary_id: diary_id,
title: title,
post_date_gmt: date,
post_content: strip_tags(content),
smiley_id: smiley_id,
author_id: user_id,
author_name: user.display_name,
attachments: filter_attachments(options[:version]),
root_comments: format_comments(nested_comments.arrange(:order => :created_at)),
post_readings: post_readings.size,
is_read: read_by(options[:current_user])
}
end
I need to change this structure a bit as follows, Actually i want group this array by the date.
{
date_01: {
[post1], [post2], [post3]
},
date_02: {
[post1], [post2], [post3]
}
}
What should I do ?
I fixed the issue as follows
post_dates = (no_of_days.days.ago.to_date..(date_as_string.to_date + no_of_days.days)).map{ |date| date.strftime("%Y-%m-%d") }
# Arrange posts details under each date
i = 0
post_dates.each do |post_date|
posts_grouped_by_date[i] = {:post_date => post_date, :posts_for_date => diary.posts_for_date(Date.parse(post_date) )}
i = i + 1
end
render json: posts_grouped_by_date.sort_by {|hash| hash['post_date']}.as_json(current_user: current_user)
replace the values of data keys to an array of arrays. like below.
{
date_01: [
[post1], [post2], [post3]
],
date_02: [
[post1], [post2], [post3]
]
}

RUBY - Correct way of doing array of hashes inside of hash

i need to do an array of hashes inside of a hash, something like this:
merit_hash => {
students => [
{
"id": id,
"name": name,
subjects => [
{
"id": id,
"grade": grade
},
{
"id": id,
"grade": grade
}
]
},
{
"id": id,
"name": name,
subjects => [
{
"id": id,
"grade": grade
},
{
"id": id,
"grade": grade
}
]
}
]
}
Right now, i just have the array of student hashes, but i dont exactly know how to put the subject array inside of it, im doing this:
merit = {}
merit["students"] = []
students.each do |students|
student_subjects = Array.new
merit["students"].push(
{
"id" => students.id,
"name" => students.name.to_s
selected_batch_subjects.each do |subjects|
grade = FinalGrades.where(batch_subject_id:subjects.id, period_id: period.id, student_id: student.id).first.value
student_subjects.push(
{
"id" => subjects.id,
"grade"=> grade
}
)
end
}
)
end
but throws this error
unexpected '}', expecting keyword_end
when i try to close the student hash... what can i do to make this work? or, whats the best way of implementing this?
Thanks!
Something like this should work:
merit = {}
merit["students"] = []
students.each do |student|
student_information = {"id" => student.id, "name" => student.name.to_s}
student_subjects = []
selected_batch_subjects.each do |subjects|
grade = FinalGrades.where(batch_subject_id:subjects.id, period_id: period.id, student_id: student.id).first.value
student_subjects.push({"id" => subjects.id, "grade" => grade})
end
student_information[:subjects] = student_subjects
merit["students"].push(student_information)
end
The important part is adding each student's subjects to the already existing hash.
Your iterations are not very clear to me but for current loop and array push you could do like this:
merit = {}
merit["students"] = []
students.each do |students|
student_subjects = []
merit["students"] << {
"id" => students.id,
"name" => students.name.to_s
}
selected_batch_subjects.each do |subjects|
grade = FinalGrades.where(batch_subject_id:subjects.id, period_id: period.id, student_id: student.id).first.value
student_subjects << {"id" => subjects.id,"grade"=> grade}
end
end

Custom json key in ruby on rails

I have an as_json method I'm overriding to include an association.
def as_json(options)
super((options || { }).merge({
:include => {:otherobject => {:include => :category}}
}))
end
So this give me json like this
{
"prop1": "val1",
"prop2": "val2",
"otherobject": {"category": {} }
}
I need to adjust the json to look like this because of my processing code.
{
"prop1": "val1",
"prop2": "val2",
"otherobject": { "otherobject": { "category": {} } }
}
I basically need to wrap the data with another key. How can I do this in rails?
def as_json(options = {})
old = super(options.merge({ :include => {:otherobject => {:include => :category}}))
new = old.slice!(:otherobject)
new[:otherobject] = old
new
end

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