gpt4 book ai didi

ruby-on-rails - ActiveRecord - "first"中的 "scope"方法返回多条记录

转载 作者:行者123 更新时间:2023-12-03 16:06:28 25 4
gpt4 key购买 nike

我是 Rails 新手,遇到了奇怪的问题。

这是一个代码示例:

class News < ActiveRecord::Base
scope :pinned, -> { where(pinned: true).first }
end

如果有带有“pinned”标志的记录没有问题,当我调用 News.pinned返回一条记录。

我在日志中看到了这个查询:
SELECT `news`.* 
FROM `news`
WHERE `news`.`pinned` = 1
ORDER BY `news`.`id` ASC
LIMIT 1

但是如果没有带有“固定”标志的记录,当我调用 News.pinned接下来的两个查询被执行:
SELECT `news`.* 
FROM `news`
WHERE `news`.`pinned` = 1
ORDER BY `news`.`id` ASC
LIMIT 1

SELECT `news`.* FROM `news`

谢谢!

最佳答案

Friendy,这里是 ActiveRecord 的方法“范围”:

1   # File activerecord/lib/active_record/scoping/named.rb, line 145
2 def scope(name, body, &block)
3 extension = Module.new(&block) if block
4
5 # Check body.is_a?(Relation) to prevent the relation actually being
6 # loaded by respond_to?
7 if body.is_a?(Relation) || !body.respond_to?(:call)
8 ActiveSupport::Deprecation.warn(
9 "Using #scope without passing a callable object is deprecated. For " "example `scope :red, where(color: 'red')` should be changed to " "` scope :red, -> { where(color: 'red') }`. There are numerous gotchas " "in the former usage and it makes the implementation more complicated " "and buggy. (If you prefer, you can just define a class method named " "`self.red`.)"
10 )
11 end
12
13 singleton_class.send(:define_method, name) do |*args|
14 if body.respond_to?(:call)
15 scope = all.scoping { body.call(*args) }
16 scope = scope.extending(extension) if extension
17 else
18 scope = body
19 end
20
21 scope || all
22 end
23 end

请注意第 21 行,如果范围为“nil”,则返回“all”。
在您的情况下,当您在第 15 行调用没有记录的“News.pinned”时,第一次咨询运行并且作用域接收“nil”,所以当它到达第 21 行时,因为作用域为“nil”,“all”正在运行第二个咨询并返回所有寄存器。

我已经通过删除第 21 行的“全部”来测试它是否覆盖了方法“范围”,而我只有一个查询

要绕过此使用:
class News < ActiveRecord::Base
def self.pinned
where(pinned: true).first
end
end

关于ruby-on-rails - ActiveRecord - "first"中的 "scope"方法返回多条记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21649804/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com