查询返回与 NOT IN () 和 IN () 的空关联
Query returning empty association with NOT IN () and with IN ()
我有模型 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
不存在于 table 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
我将 Invitation
的 scope
的条件反转为以下内容:
scope :pending, -> { where(referral_email: Person.select(:email).distinct) }
但是预期的查询一直返回空关系
@person.sent_invitations.pending.count # => 0
有人知道会发生什么吗?
代码在测试中运行良好,我们在生产中发现了这个问题。
查询
原始try的查询
SELECT "invitations".* FROM "invitations" WHERE "invitations"."sponsor_id" = AND ("invitations"."referral_email" NOT IN (SELECT DISTINCT "person"."email" FROM "person"))
第二次尝试查询
SELECT "invitations".* FROM "invitations" WHERE "invitations"."sponsor_id" = AND ("invitations"."referral_email" IN (SELECT DISTINCT "person"."email" FROM "person"))
table 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
电子邮件会造成这种行为。感谢您的帮助。
我有模型 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
不存在于 table 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
我将 Invitation
的 scope
的条件反转为以下内容:
scope :pending, -> { where(referral_email: Person.select(:email).distinct) }
但是预期的查询一直返回空关系
@person.sent_invitations.pending.count # => 0
有人知道会发生什么吗?
代码在测试中运行良好,我们在生产中发现了这个问题。
查询
原始try的查询
SELECT "invitations".* FROM "invitations" WHERE "invitations"."sponsor_id" = AND ("invitations"."referral_email" NOT IN (SELECT DISTINCT "person"."email" FROM "person"))
第二次尝试查询
SELECT "invitations".* FROM "invitations" WHERE "invitations"."sponsor_id" = AND ("invitations"."referral_email" IN (SELECT DISTINCT "person"."email" FROM "person"))
table 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
电子邮件会造成这种行为。感谢您的帮助。