我有一个应用,其中let re = "^(([^<>()\\[\\]\\.,;:\\s@\\\"]+(\\.[^<>()\\[\\]\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@(([^<>()[\\]\\.,;:\\s@\\\"]+\\.)+[^<>()[\\]\\.,;:\\s@\\\"]{2,})$"
创建了一个User
,以便从其他Transaction
购买Item
。我突然在User
的一种方法中遇到find_by
时遇到困难。我想找到涉及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
id#5(其Transaction
为7,item_id
为4),然后调用{{1 }},我大概会得到recipient_id
#5。查询的SQL输出为t.item.first_find
。
哪个很棒!这就是我想要的输出。但是令我感到困惑的是,它返回了这个:
Transaction
有人知道为什么吗?谢谢!
编辑1
所以我认为我已经解决了?在遇到由于某些原因将过多的搜索参数放入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 ..... >
这样做
where
我不确定为什么。有人知道吗?
编辑2
AND运算符应与OR运算符分开。
答案 0 :(得分:2)
回答原因。 这就是SQL operator precedence的工作方式。进一步的解释是here。因此,当您将其中断到builds a new relation的另一个“ where”子句时,这是根据参数中的条件过滤当前关系的结果。 source code is here。
让我展示其他解决方案。
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
答案 1 :(得分:1)
我认为您应该使用where
子句,而不要使用find_by
,
class Item < ApplicationRecord
def first_find
Transaction.where("item_id = ? AND recipient_id = ? AND state != ? OR state != ? OR state != ?", self.id, author.id, :ignored, :declined, :unapproved)
end
end
如果您使用find语句,这将返回ActiveRecord::Relation
(记录集合)而不是仅一条记录