[英]How to “merge” more than one 'ActiveRecord::Associations' and one or more scope methods?
[英]ActiveRecord - “first” method in “scope” returns more than one record
我是Rails的新手,我有一個奇怪的問題。
這是一個代碼示例:
class News < ActiveRecord::Base
scope :pinned, -> { 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.