Get count of one-to-many records efficiently - sql

I have two tables: App (with a release_id field) and User.
Models
class App < ActiveRecord::Base
has_one :user
end
class User < ActiveRecord::Base
belongs_to :app
end
Class
class Stats::AppOverview
def initialize(from:, apps:)
#from = from || Date.new(2010)
#apps = apps
end
def total_count
{ apps: { total: total_app, with_user: app_with_user } }
end
private
def app_since
#apps.where('created_at >= ?', #from)
end
def total_app
devices_since.count
end
def app_with_user
User.where(app: app_since).count
end
end
I would like to return
the number of app records for a given array of release_id
the number of app records that belong to each user, satisfying other criteria
This is how I use the class
Stats::AppOverview.new(from: 1.month.ago.iso8601,
apps: App.where(release_id: [1,2,3,4,5,19,235]).total_count
#=> { apps: { total: 65, with_user: 42 } }
For the moment I do it in two queries, but is it possible to put them in the same query? Is this possible using active record?

Related

Rails admin gem, polymorphic association

How to get the queried data having polymorphic association
I have an 3 models
class Picture < ApplicationRecord
belongs_to :imageable, polymorphic: true
end
class Employee < ApplicationRecord
has_many :pictures, as: :imageable
end
class Product < ApplicationRecord
has_many :pictures, as: :imageable
end```
Employee and Product have column **is_active**.
In rails admin dropdown. I want to display the data where employee and product is **is_active = true.**
Have tried multiple ways to achieve this.
Please let me know if there is any solution?
You can write a custom scope in picture model as below
scope :list_active(imageable_type), -> {
where(imageable_type: imageable_type)
.joins("INNER JOIN #{imageable_type.pluralize} ON
{#imageable_type.pluralize}.id = imageable_id AND
imageable_type = '#{imageable_type}'")
.where('#{imageable_type.pluralize}.is_active = ?', true)
}
Then you can simply list and use the response.
E.g result = []
result << Image.list_active('Employee')
result << Image.list_active('Product')

Find cards with today date when user receive mails in RoR

Every day I need to send letters to users with today's tasks.
For do this I need to find all users who are allowed to send letters, and among these users to find all cards that have a deadline today. The result is three array elements with a nil value. How is this better done and right?
#users = User.all {|a| a.receive_emails true}
#user_cards = []
#users.each_with_index do |user, index|
#user_cards[index] = user.cards.where(start_date: Date.today).find_each do |card|
#user_cards[index] = card
end
end
My user model:
class Card < ApplicationRecord
belongs_to :user
# also has t.date "start_date"
end
My card model:
class User < ApplicationRecord
has_many :cards, dependent: :destroy
# also has t.boolean "receive_emails", default: false
end
Something like #cards_to_send = Card.joins(:users).where("users.receive_emails = true").where(start_date: Date.today)
Have a look at https://guides.rubyonrails.org/active_record_querying.html#specifying-conditions-on-the-joined-tables for the docs on how to query on a joined table.
You could do this with a SQL join like this
User.joins(:cards).where(receive_emails: true, cards: { start_date: Date.today })
https://guides.rubyonrails.org/active_record_querying.html#joining-tables

ActiveRecord query based on multiple objects via has_many relationship

I have a Product class that has_many Gender through Connection class instances. I want to query to find products that have both end_a and end_b present. The current class method works with 2 caveats:
Fails to return correctly if searching where end_a and end_b are the same. Instead should search if product has 2 instances, not just one of object.
Returns an Array when I want an ActiveRecord_Relation.
The class method .query is below, any feedback or ideas are appreciated.
class Product < ActiveRecord::Base
has_many :connections, dependent: :destroy, as: :connectionable
has_many :genders, through: :connections
def self.query(end_a, end_b)
search_base = active.joins(:connections)
end_a_search = search_base.where(connections: { gender_id: end_a } )
end_a_search & search_base.where(connections: { gender_id: end_b } )
end
end
ps: Once this is figured out will likely move this to a scope for Product
class Product < ActiveRecord::Base
has_many :connections, dependent: :destroy, as: :connectionable
has_many :genders, through: :connections
scope :with_genders, -> (end_a, end_b) {
relation = joins('INNER JOIN connections c1 ON c1.connectionable_id = products.id AND c1.connectionable_type = \'Product\'')
.joins('INNER JOIN connections c2 ON c1.connectionable_id = c2.connectionable_id AND c2.connectionable_type = \'Product\'')
.where(c1: {gender_id: end_a}, c2: {gender_id: end_b})
.group('products.id')
end_a == end_b ? relation.having('COUNT(products.id) > 1') : relation
}
end

Get associated ActiveRecord::Relation from complex query

I have the following AR models:
class Checkin < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
has_many :checkins
end
Let's say I have a complex query on checkins and users, for example, Checkin.nearby.today and User.friends_of(john). Is there a straightforward way I can derive an ActiveRecord::Relation of Users? The end result would be friends of John who have checked in nearby today.
I would like the end result to be an instance of ActiveRecord::Relation.
Thanks!
This should do it:
users = User.friends_of(john)
users = users.joins(:checkins).where(checkins: { checkin_date: Date.today })
users = users.where( # your logic to determine the nearby )
As you can see, there is the logic about the nearby scope missing.
In a custom method:
def self.friends_checked_nearby_at_date(friend, nearby = true, date = Date.today)
users = User.friends_of(friend)
users = users.joins(:checkins).where(checkins: { checkin_date: date })
users = users.where( # your logic for the nearby scope ) if nearby.present?
return users
end
# usage:
User.friends_checked_nearby_at_date( User.first )
# or
User.friends_checked_nearby_at_date( User.first, true, Date.today-1.week )
# or
User.friends_checked_nearby_at_date( User.first, false )
# etc.

How can I write this record search in rails 3

#find the most recent news item for a specific locale
def self.find_most_recent_news_for_locale
first(:include => :news_item_detail,:conditions => ["news_items.created_at= ? AND news_item_details.locale = ?", maximum(:created_at), I18n.locale])
end
The Models
class NewsItem < ActiveRecord::Base
has_one :news_item_detail
end
class NewsItemDetail < ActiveRecord::Base
belongs_to :news_item
end
In Rails 3, you should use the where method for creating conditions:
def self.find_most_recent_news_for_locale
where("news_items.created_at = ? AND news_item_details.locale = ?",
maximum(:created_at),
I18n.locale).includes(:news_item_details).first
end
You might want to watch episode #202 of Railscasts as a quick tutorial.