ruby-on-rails - rails find_by 返回不正确的记录?
问题描述
我有一个应用程序,其中 aUser
创建一个Transaction
从Item
不同的User
. 我突然对 .in find_by
one 方法有困难Item
。我想找到第一个Transaction
涉及Item
调用它的对象,并且我想通过搜索许多无效状态来进一步限制该结果。
class Item < ApplicationRecord
def first_find
Transaction.find_by("item_id = ? AND recipient_id = ? AND state != ? OR state != ? OR state != ?", self.id, author.id, :ignored, :declined, :unapproved)
end
end
无论如何,它的作用是返回Transaction
我的数据库中的第一个。这不是预期的行为。所以在控制台中,如果我想t = Transaction.last
缓存Transaction
id #5(它的 anitem_id
为 7,arecipient_id
为 4),然后调用t.item.first_find
,我大概会得到Transaction
#5。对此的 SQL 输出是 query is Transaction Load (1.1ms) SELECT "transactions".* FROM "transactions" WHERE (item_id = 7 AND recipient_id = 4 AND state != 'ignored' OR state != 'declined' OR state != 'unapproved') LIMIT $1 [["LIMIT", 1]]
。
太棒了!这就是我想要的输出。但令我困惑的是,它返回了这个:
#<Transaction id: 2, sender_id: 1, recipient_id: 2, item_id: 9 ..... >
有谁知道为什么?谢谢!
编辑 1
所以我想我已经解决了?在将太多搜索参数放入where
子句中之前,我遇到过这个问题,因为某种原因会弄乱它。
所以虽然这不起作用
Transaction.find_by("item_id = ? AND recipient_id = ? AND state != ? OR state != ? OR state != ?", self.id, author.id, :ignored, :declined, :unapproved)
这确实
Transaction.where("item_id = ? AND recipient_id = ?", self.id, author.id).where("state != ? OR state != ? OR state != ?", :ignored, :declined, :unapproved).first
不过,我不完全确定为什么。有人知道吗?
编辑 2
AND 运算符应与 OR 运算符分开。
解决方案
answering why. that's how SQL operator precedence works. more explanation is here. so when you break it to another "where" clause that builds a new relation, which is the result of filtering the current relation according to the conditions in the arguments. the source code is here.
let me show other solutions.
1.
Transaction.where(item_id: self.id, recipient_id: author.id).where.not(state: [:ignored, :declined, :unapproved]).first
2.
recipient_transactions = Transaction.where(item_id: self.id, recipient_id: author.id)
active_transactions = Transaction.where.not(state: [:ignored, :declined, :unapproved])
result = recipient_transactions.merge(active_transactions).first # this buils a single query
推荐阅读
- django - 跨域请求被阻止:同源策略不允许在 http://127.0.0.1:8000/api/task-list/ 读取远程资源
- php - PHP多维数组组合具有相同索引号的值
- python - 排除特定列
- php - HTML DOM 用点替换逗号
- c++ - 我在地图 C++ 中遇到了 count() 的意外行为
- python - 如何使用python烧瓶从firebase auth注销/注销
- spring-boot - 如何使用 schema-h2.sql
- python - 当我使用 SMTP 尝试发送电子邮件时,为什么我的代码返回错误
- sql - 用于对数据库表中的实际数据进行排序的 SQL
- ubuntu - ubuntu 服务器上的 Netplan 和 DHCP 热点:租约在哪里?