【发布时间】:2020-02-15 07:07:27
【问题描述】:
我在 Rails 4.1 项目中发现 ActiveRecord#find_by 的以下用法:
booking = Booking.find_by(member_id: Member.where(id: 1).select(:id))
但是,将项目升级到 Rails > 4.2 后,此查询返回 nil。
在 Rails 4.2 中,上述查询生成以下 SQL:
SELECT "bookings".* FROM "bookings" WHERE "bookings"."member_id" = $1 LIMIT 1 [["member_id", nil]]
一个“Booking”属于一个“Member”,一个“Member”有多个“Booking”。
有人知道或明白为什么吗?我有兴趣解释一下。
将 select 替换为 pluck 会恢复预期的行为:
booking = Booking.find_by(member_id: Member.where(id: 1).pluck(:id))
生成的查询:SELECT "bookings".* FROM "bookings" WHERE "bookings"."member_id" = 1 LIMIT 1
编辑:数据库中存在 ID 为 1 的成员记录。
Member.where(id: 1).select(:id) 在 Rails 4.2 中返回以下结果和 SQL 语句:
=> #<ActiveRecord::Relation [#<Member id: 1>]>
SELECT "members"."id" FROM "members" WHERE "members"."id" = $1 [["id", 1]]
【问题讨论】:
-
嗯,您切换了
where和find_by的位置,现在我无法再复制它了。你确定最后的编辑是正确的吗?Member.find_by(id: 1).select(:id)总是返回 nil。当前的表单应该可以正常工作,尽管效率很低(如果您有成员 ID,只需立即使用它,而不是检索具有该 ID 的 所有成员,然后 选择他们的身份证)。 -
感谢 nathanvda 的评论。我只编辑了从“编辑:”开始的问题的最后一部分。
Member.where(id: 1).select(:id)确实返回 ActiveRecord::Relation 但与Booking.find_by(member_id: Member.where(id: 1).select(:id))结合使用,Rails > 4.2 中的结果为零,这是我的问题。 -
啊好吧,那一定是看错了。我现在看到了,我也可以复制它。如果我写
.find_by(member_id: Member.where(id: 1).select(:id)),我会得到nil。我不明白,因为find_by的实现只是where(*args).take。如果我使用where(..).first或where(...).take它就可以工作,但是用相同的参数编写find_by总是返回nil?嗯嗯有趣... -
我有完全相同的发现,nathanvda。嗯……
标签: ruby-on-rails ruby-on-rails-4.2 ruby-on-rails-4.1