Rails Active Record: Missing column in group query - ruby-on-rails

I saw that someone had the same question but the solution was not clear to me:
Rails ActiveRecord: Missing column in grouping query
I wrote a query in Active Record as follows:
shortened_urls.joins(:visits)
.group(:short_url, :long_url)
.select('long_url, short_url, COUNT(visits.id) as number_of_visits')
.order(Arel.sql('COUNT(visits.id) DESC'))
.limit(5)
And I get the following results:
[#<ShortenedUrl:0x00005585fbb8fb60
id: nil,
long_url: "jfjfhgfhduiuyyyyyyyyyyyyyyyyyyyyyyyyyy.k",
short_url: "Bn_N2QPoSE1VlNYqWXUL9A">,
#<ShortenedUrl:0x00005585fbb8f9f8
id: nil,
long_url:
"https://help.ubuntu.com/community/PostgreSQL#restarting_the_server",
short_url: "Dte6_CUnAdxJgv_jUBwXIg">,
#<ShortenedUrl:0x00005585fbb8f8b8
id: nil,
long_url: "jjjfhusirtyuizyfsvqdhjdhdfv",
short_url: "CQa8n1o-f2oEwKy8j_Zo9Q">,
#<ShortenedUrl:0x00005585fbb8f778
id: nil,
long_url: "uezfhueizyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy.kkkk",
short_url: "4S1uC8yl0a8HlK6xJq23FQ">,
#<ShortenedUrl:0x00005585fbb8f638
id: nil,
long_url: "blahffhhfhfhhfhfhffhfhhfhhfhfhfhfhhfhfh.com",
short_url: "_NZSroaeyvVqvOKoPAieng">]
As you can see, the column 'number_of_visits' doesn't appear and the id's are all nil;
Does anyone have any idea how to solve this ? Or maybe explain to me what was the solution for the other similar question posted?
Thank you very much

Related

How to query the Noticed gem json field

I am using Noticed gem for my notifications and I am trying to query for the notifications related to the post.
The notification stores the post as an object inside params.
#<Notification id: 10, params: {:post=>#<Post id: 3}>
I can target like
notification.params[:post][:id]
=> 3
What I am trying to accomplish is something like this:
Notifications.where(params[:post][:id] => 3)
Is there a way to do that or my approach should be different?
Edited:
Here is an example of a notification in the database:
#<Notification id: 10, recipient_type: "User", recipient_id: 8, type: "MessageNotification", params: {:user=>#<User id: 3, email: "test2#test2.com", created_at: "2021-01-06 23:34:46", updated_at: "2021-04-15 17:47:54", admin: true>, :conversation=>#<Mailboxer::Conversation id: 6, subject: "Hello", created_at: "2021-05-14 00:14:41", updated_at: "2021-05-14 00:26:06">}, read_at: nil, created_at: "2021-05-14 00:26:06", updated_at: "2021-05-14 17:11:50">
squema.rb
t.jsonb "params"
A query suggested by #Joel_Blum and the slq call:
>> current_user.notifications.where('params #> ?', {conversation: {id: 6}}.to_json).to_sql
=> "SELECT \"notifications\".* FROM \"notifications\" WHERE \"notifications\".\"recipient_id\" = 8 AND \"notifications\".\"recipient_type\" = 'User' AND (params #> '{\"conversation\":{\"id\":6}}')"
Returns => #<ActiveRecord::AssociationRelation []>
It seems the gem creates either a jsonb or json column depending on your db.
So what want is perform a search on a json(b) column
For postgres for example it can be done like this
Notification.where('params #> ?', {post: {id: 3}}.to_json)
For whatever reason I am getting an empty array on a notification that I am sure exists.
query: Notification.where('params #> ?', {comment: {id: testc.id}}.to_ json)
SQL: "SELECT \"notifications\".* FROM \"notifications\" WHERE (params #> '{\"comment\":{\"id\":656}}')"
Noticed has a built in way of querying for objects you send in the params.
If you add has_noticed_notifications to the Post model, you should then be able to call #post.notifications_as_post
This is in the Noticed readme here. I definitely came here and found this question before I found the details in the readme!

Rails where, sort and combine same table

I have a model called extra. Here how it looks like;
#<Extra id: nil, name: nil, price: nil, per: nil, compulsory: nil, online_payment: nil, payment_per_person: nil, is_included: nil, created_at: nil, updated_at: nil, user_id: nil>
I would like to first sort them by is_included where it is true. Then I want to sort where compulsory is true, lastly where compulsory is false. Then I want to combine them.
Basically, I want to group them because user can save them unordered. Then remove if anyone exists twice.
Shall I do it on the view or before_save callback?
Thanks
Extra.order('is_included desc, compulsory desc') will return your desired result and you should never execute SQL queries on view.

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

Trying to iterate over a activerecord to fetch the values

I am trying iterate through following active record
#<ActiveRecord::Relation [#<WantedEquipment id: 1, identifier: "WEID-0000001", title: "Wanted a Test Equipment", category_id: 1, sub_category_id: 3, listing_type: nil, description: "This is a test wanted equipment.", name: "John", email: "john.user#mailinator.com", user_id: nil, status: 1, created_at: "2017-02-25 16:10:35", updated_at: "2017-02-25 16:10:35">, #<WantedEquipment id: 2, identifier: "WEID-0000002", title: "Wanted a Test Equipment1", category_id: 1, sub_category_id: 3, listing_type: nil, description: "This is a test wanted equipment.", name: "John", email: "john.user#mailinator.com", user_id: nil, status: 1, created_at: "2017-02-25 16:10:50", updated_at: "2017-02-25 16:10:50">]>
To collect the values of column email. I am quiet new to ruby.
I ran the following on rails console.
WantedEquipment.all.each do |eq|
eq.email
end
As a result I got the whole table again instead of just the emails. Could somebody please guide me here?
If all you need are the email addresses and not the actual AR objects, then use this:
WantedEquipment.pluck(:email)
This will translate into the following SQL:
SELECT "wanted_equipments"."email" FROM "wanted_equipments"
You can select all email using following way
WantedEquipment.select('email')
If possible always use database level memory instead of system.
You can use either select or pluck here.
WantedEquipment.pluck(:email)
Or
WantedEquipment.select(:email)
Depends upon your result set performance you can use anyone.

has value in a console but it's nil in my controller and my view?

I have this strange behavior and I don't undertand why. Here is the thing:
I have this record in my payment model:
1.9.3p286 :019 > u.payment.last
Payment Load (0.3ms) SELECT "payments".* FROM "payments" WHERE "payments"."user_id" = 10
=> [#<Payment id: 37, bank_name: "Mercantil", plan: "Plan Uno", date: "2012-12-25", reference_number: "3452435", coupon: "", user_id: 10, created_at: "2012-12-25 21:56:12", updated_at: "2012-12-25 21:58:31", active_until: "2013-01-24">]
As you can see, I have one record for my user: 10.
If I try to get the same information in my controller I don't get any exception, but
#user.payment.last.active_until
is empty, the same in the view.
For example if I try this in my view:
<%= #user.payment.last.active_until %>
I didn't get anything, is blank.
If I try this
<%= #user.payment %>
I got the same as my console
[#<Payment id: 37, bank_name: "Mercantil", plan: "Plan Uno", date: "2012-12-25", reference_number: "3452435", coupon: "", user_id: 10, created_at: "2012-12-25 21:56:12", updated_at: "2012-12-25 21:58:31", active_until: "2013-01-24">, #<Payment id: nil, bank_name: nil, plan: nil, date: nil, reference_number: nil, coupon: nil, user_id: 10, created_at: nil, updated_at: nil, active_until: nil>]
I really don't understand what happend here. Any help please.
Thanks in advance.
PD: The user could has many payments, but I need just the last.
It's not the same as in your console. In the console you get have one record, but in the view you get two - the record that you see in the console, and another blank one.
I'm guessing the blank one is the one that you are using for the form tag helper for the form used to create a new Payment record, but that's also the one that last returns. Either take the one before last, or filter for saved records before you call last.

Resources