我有模型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
。 / p>
场景::我尝试从@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
的{{1}}的条件反转为:
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"))
答案 0 :(得分:0)
表Persona
中有一些记录带有email: nil
。删除它们可使查询按预期方式工作:
@person.sent_invitations.pending.count # => 1
@person.sent_invitations.first.referral_email # => 'some_email@example.com'
@person.sent_invitations.pending.first.referral_email # => 'some_email@example.com'
scope
保持原始状态:
scope :pending, -> { where.not(referral_email: Persona.select(:email).distinct) }
我将研究为什么nil
电子邮件会导致这种行为。感谢您的帮助。