I just noticed that using .size or .count on a query that has joins gives unexpected results.
User.some_scope.size #=> 10
User.joins(:associations).some_scope.size #=> 10 + associated object count
How do I get the count of Users that fit the scope no matter what I join onto the table?
Some of the actual code:
class User < ActiveRecord::Base
has_many :tracking_logs, class_name: "Tracking::Log", dependent: :destroy
end
class Tracking::Log < ActiveRecord::Base
belongs_to :user
end
User.where(created_at: Time.now-1.day..Time.now).size #=> 18
SQL: SELECT COUNT(*) FROM "users" WHERE ("users"."created_at" BETWEEN '2015-05-25 10:40:11.423142' AND '2015-05-26 10:40:11.423741')
User.joins(:tracking_logs).where(created_at: Time.now-1.day..Time.now).size #=> 3188
SQL: SELECT COUNT(*) FROM "users" INNER JOIN "tracking_logs" ON "tracking_logs"."user_id" = "users"."id" WHERE ("users"."created_at" BETWEEN '2015-05-25 10:41:15.260113' AND '2015-05-26 10:41:15.260684')
I expect .size to be applied only to the base model I call the query on, anything else is just confusing.
NB, being explicit about which model's created_at to check does not change the result e.g.
User.joins(:tracking_logs).where( users: { created_at: Time.now-1.day..Time.now } ).size #=> 3188
SQL: SELECT COUNT(*) FROM "users" INNER JOIN "tracking_logs" ON "tracking_logs"."user_id" = "users"."id" WHERE ("users"."created_at" BETWEEN '2015-05-25 10:49:29.485508' AND '2015-05-26 10:49:29.486120')
User attributes:
:id => :integer,
:category => :string,
:email => :string,
:created_at => :datetime,
:updated_at => :datetime,
:locale => :string,
:original_email => :text,
:registration_id => :integer,
:first_name => :text,
:login_count => :integer,
:offer_type => :text,
:cid => :string,
:fb_like_status => :integer,
:product_purchases => :text
Tracking::Log attributes:
:id => :integer,
:user_id => :integer,
:tracking_referer_id => :integer,
:to => :string,
:controller_name => :string,
:action_name => :string,
:tracking_activity_id => :integer,
:time_since_last_log => :integer,
:created_at => :datetime,
:updated_at => :datetime
ActiveRecord::Base.logger = Logger.new(STDOUT)and showing SQL that gets generated for the first and the second query? - SkyWriter