ActiveRecord – “范围”中的“第一个”方法返回多个记录

我是Rails的新手,我有一个奇怪的问题。

这是一个代码示例:

class News  { where(pinned: true).first } end 

如果有“固定”标志的记录没有问题,当我调用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 

如果范围是“nil”则返回第21行,然后返回“all”。
在你的情况下,当你在第15行没有记录的情况下调用“News.pinned”时,第一次参考就会运行,范围会收到“nil”,所以当它到达第21行时,由于范围是“nil”,所以“all”正在运行第二次咨询并返回所有寄存器。

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

绕过这个用途:

 class News < ActiveRecord::Base def self.pinned where(pinned: true).first end end