У меня есть модели Invitation
и Person
.Атрибуты и отношения, важные в этом вопросе, следующие:
# has sponsor_id, referral_email
class Invitation < ApplicationRecord
belongs_to :sponsor, class_name: 'Person'
belongs_to :referral, class_name: 'Person',
foreign_key: :referral_email, primary_key: :email
scope :pending, -> { where.not(referral_email: Person.select(:email).distinct) }
end
# has id, email
class Person < ApplicationRecord
has_many :sent_invitations, class_name: 'Invitation',
foreign_key: :sponsor_id
has_many :received_invitations, class_name: 'Invitation',
foreign_key: referral_email,
primary_key: :email
has_many :referrals, class_name: 'Persona', through: :sent_invitations
has_many :sponsors, class_name: 'Persona', through: :received_invitations
end
Я нашел запись Invitation
, которой ее referral_email
не было в таблице Person
, а ее sponsor_id
былодействительного Person
.
Сценарий: Из @sponsor
я попытался узнать, сколько у него sent_invitations.pending
, но запрос вернул пустое отношение:
@sponsor.sent_invitations.pending.count # => 0
Но это результат других запросов, которые я выполняю при попытке отладки:
@sponsor.sent_invitations.count # => 1
@sponsor.referrals.count # => 0
@sponsor.sent_invitations.first.referral_email # => 'some_email@example.com'
Person.pluck(:email).include? @sponsor.sent_invitations.first.referral_email # => false
Я инвертировал условие scope
из Invitation
в следующее:
scope :pending, -> { where(referral_email: Person.select(:email).distinct) }
Но предполагаемый запрос продолжал возвращать пустое отношение
@person.sent_invitations.pending.count # => 0
Кто-нибудь знает, что может произойти?
Код работал нормально натестирование и мы обнаружили эту проблему на производстве.
Запросы
Запрос оригинальной попытки
SELECT "invitations".* FROM "invitations" WHERE "invitations"."sponsor_id" = $1 AND ("invitations"."referral_email" NOT IN (SELECT DISTINCT "person"."email" FROM "person"))
Запрос второй попытки
SELECT "invitations".* FROM "invitations" WHERE "invitations"."sponsor_id" = $1 AND ("invitations"."referral_email" IN (SELECT DISTINCT "person"."email" FROM "person"))