Working on Rails 6.1
I've got this base class:
class Post < ApplicationRecord
end
And these two subclasses representing a face-to-face lesson and it's live transmission:
class Live < Post
belongs_to :in_person_live,
foreign_key: :live_of_in_person_live_id,
class_name: 'InPersonLive',
required: false,
inverse_of: :online_live,
touch: true
end
class InPersonLive < Post
has_one :online_live,
class_name: 'Live',
foreign_key: 'live_of_in_person_live_id',
inverse_of: :in_person_live,
touch: true
end
I'd like to query for face-to-face lessons without a live transmission.
I came up with this, which seems to work:
InPersonLive.where.not(id: Live.where.not(live_of_in_person_live_id: nil).select(:live_of_in_person_live_id)).count
But was wondering why this doesnt work:
InPersonLive.where.missing(:online_live).count
I'd expect the .missing to return the same result but it always returns 0.
The generated SQL is different in both cases but again I don't understand why the result is different, seems to me like they should return the same set.
InPersonLive.where.not(id: Live.where.not(live_of_in_person_live_id: nil)).count generates:
SELECT COUNT(*) FROM "posts" WHERE "posts"."type" = $1 AND "posts"."id" NOT IN (SELECT "posts"."live_of_in_person_live_id" FROM "posts" WHERE "posts"."type" = $2 AND "posts"."live_of_in_person_live_id" IS NOT NULL) [["type", "InPersonLive"], ["type", "Live"]]
while InPersonLive.where.missing(:online_live).count generates:
SELECT COUNT(*) FROM "posts" LEFT OUTER JOIN "posts" "online_lives_posts" ON "online_lives_posts"."live_of_in_person_live_id" = "posts"."id" AND "online_lives_posts"."type" = $1 WHERE "posts"."type" = $2 AND "posts"."id" IS NULL [["type", "Live"], ["type", "InPersonLive"]]