Active Record Grouping in Ruby On Rails - ruby-on-rails

record = #<ActiveRecord::AssociationRelation
[#<User id: 2, store_id: 3,location: 'xxx'>,
#<User id: 4, store_id: 3,location:'yyy'>,
#<User id: 5, store_id: 4,location:'zzz'>,
#<User id: 6, store_id: 4,location:'aaa'> ]>
How to group location in comma seperated form based on store_id in ruby to get the result as,
The location of store-id(3) should be combained with comma as (yyy,xxx),
then the location of store-id(4) should be combained with comma as (zzz,aaa)
#< store_id: 3,location:'yyy,xxx'>
#< store_id: 4,location:'zzz,aaa'>

Using Enumerable.group_by you can do it this way:
User.all.group_by(&:store_id).map{|store_id,records| {store_id: store_id, location: records.map(&:location).join(',')}}
If you want to do the grouping on database level, using the group method from ActiveRecord, it is required to have a function on the database that takes care of the concatenation, so the solution would depend on the database being used.
For example, in MySQL (see Can I concatenate multiple MySQL rows into one field?)
User.group("store_id").select("store_id, GROUP_CONCAT(location SEPARATOR ',') as location")

Related

Rails not getting average using postgresql

I'm working on learning Active Record and queries and wrote a query within my rails console that I thought should work pretty easily, but it is not.
Statistic.select("player_id, sum(oreb)").group("player_id").limit(5)
This returns the following Active Record Relation
[#<Statistic:0x007f801b2f0240 id: nil, player_id: 1>, #<Statistic:0x007f801b2f00b0 id: nil, player_id: 2>, #<Statistic:0x007f801fcffed0 id: nil, player_id: 3>, #<Statistic:0x007f801fcffd40 id: nil, player_id: 4>, #<Statistic:0x007f801fcffbb0 id: nil, player_id: 5>]
oreb does exist, i can use pgAdmin or the psql console tool to execute the query directly
Select player_id, sum(oreb) from Statistics
GROUP BY player_id
LIMIT 5
And get the a result that includes oreb.
I've done a bit of research, and can't find a simple reason for why this is not working...any thoughts would be appreciated...
Model Statistic doesn't have column for sum(oreb) and can't be mapped to model's attributes but data is retrieved. You can extract it by given name to sum.
stats = Statistic.select("player_id, sum(oreb) total").group("player_id").limit(5)
puts stats.first.total

How to insert new key value pair into fetch database object in rails 4

I am developing application in rails 4 where i have to insert new key value pair after fetch record and response back.
I fetch 10 records and its loop every record look like below:
#<User id: 29, email: "two#gmail.com", password_digest: "$2a$10$Ty2NOaVCsAK6sQwdQJHMgen9/fNkeDb.TmYY5Xyk/M5i...", fname: "bondalu2", lname: "two", created_at: "2014-08-22 06:09:46", updated_at: "2014-08-22 22:14:21", username: "bondalutwo", dob: "1950-01-01", zip: "32658", status: 1, image_id: 14, pref_age_low: 18, pref_age_high: 18, pref_radius: 5, pref_zip: 32658, token: "289c9d805697fa5dbec705c9574a7e2d">
How to insert new key "profile_img" and its value "abc.jpg" (diff for every user) into above every object of users.
Like: #<User id: 29, email: "two#gmail.com", profile_img: "abc.jpg", password_digest:"...
I tried but not getting. How to do it.
Does your User table have a column called 'profile_img'?
From the above code it seems that it doesn't have it. So, firstly you need to add a migration to add a 'profile_img' column to your User table.
After that you can do this :
value = 'Some Value'
#users.each{|user| user.update_attributes(:profile_img => value)}

collect an array of hashes that matches a record ruby

I have an array of hashes with various records in them. I have a value which I want to cross reference against that array and if it matches, pull out that record and use it.
>> concurrent_jobs.job_products
=> #<ActiveRecord::Associations::CollectionProxy [#<JobProduct id: 365, job_id: 91, product_id: 181, quantity: 3, frozen_cache: {}, created_at: "2014-08-13 15:54:21", updated_at: "2014-08-14 09:56:37">, #<JobProduct id: 366, job_id: 91, product_id: 363, quantity: 1, frozen_cache: {}, created_at: "2014-08-13 16:02:40", updated_at: "2014-08-13 16:02:40">]>
So let's say in the above array I want to collect the entire record that matches product_id: 363 and then begin to use its other information such as quantity etc. How do I do it?
here is the method I have written so far
def product_quantity_in_current_unconfirmed_jobs(concurrent_jobs, original_product)
concurrent_jobs.job_products.map do |x|
b = x.product.id
if b == original_product.id
raise
end
end
end
I am sure there is a more eloquent way to do this. I'm just learning
Assuming that this is an ActiveRecord association, you probably just want to query the association directly:
concurrent_jobs.job_products.where(product_id: 363).first
This will execute a SQL query to return just that one record (you can see that query by tailing your log/development.log), rather than returning all the records and forcing you to iterate them in your app.
That said, in the general case, if this were not ActiveRecord and you had an array of hashes, you could use Enumerable#select (to grab all matching records) or Enumerable#detect (to grab the first matching record):
matching_records = array.select {|entry| entry[:product_id] == 363 }
or:
first_matching_record = array.detect {|entry| entry[:product_id] == 363 }

How would I get the names and id's out of this object?

I have an object called #groups
When I enter #groups into the console it returns this:
[#<Group id: 2, name: "another test group", creator_id: 6, updater_id: 6, created_at: "2013-11-22 17:04:14", updated_at: "2013-11-22 17:04:14">, #<Group id: 1, name: "test group", creator_id: 6, updater_id: 6, created_at: "2013-11-20 17:50:28", updated_at: "2013-11-20 17:50:28">]
I want to make an select field and populate it with each group using the options_for_select() method
So, I was going to try to get the names and id's of each group and populate it that way but I don't know how to do this.
Rather than mapping the attributes you want out of an array, you should do this the rails way by using either the options_from_collection_for_select or, even easier, you can use collection_select in your form.
You'll want to use map for this:
#groups.map {|group| [group.name, group.id]}
This will return an array of arrays, with each containing [group.name, group.id].

Rails active record query, serialized array

Suppose I have Users data that store array of pet in String datatype
[
#<User id: 1, name: "John", pets: "---\n- cat\n- dog\n- bunny\n- ''\n">,
#<User id: 2, name: "Pete", pets: "---\n- dog\n- bunny\n- ''\n">,
#<User id: 3, name: "Jack", pets: "---\n- cat\n- ''\n">,
#<User id: 4, name: "Kurt", pets: "---\n- cat\n- bunny\n- ''\n">
]
Can i get all users that has a cat? Maybe something like User.find_all_by... or User.where(....) or anything that return as a relation? So i can order with active record query.
I know i can get all users that has a cat with
User.all.select{|s| YAML.load(s.pets).include?'cat'}
, but it convert to array that cannot be ordered with active record query.
thx for helping.
You could use simple SQL to see if 'cat' shows up in the serialized column.
User.where('pets LIKE "%cat%"').all
You need to normalize your data, add Pet model and set has_and_belongs_to_many association between theese models.

Resources