Activerecord 对于Rails 4,Model.scoped不推荐使用,但是Model.all可以';我不能替换它

Activerecord 对于Rails 4,Model.scoped不推荐使用,但是Model.all可以';我不能替换它,activerecord,ruby-on-rails-4,Activerecord,Ruby On Rails 4,起始Rails 4,Model.scoped现在已被弃用 弃用警告:Model.scoped已弃用。请改用Model.all。 但是,在Model.scoped和Model.all中存在差异,即scoped.scoped返回一个范围,而all.all运行查询 在轨道3上: > Model.scoped.scoped.is_a?(ActiveRecord::Relation) => true 在轨道4上: > Model.all.all.is_a?(ActiveRecord

起始Rails 4,
Model.scoped
现在已被弃用


弃用警告:Model.scoped已弃用。请改用Model.all。

但是,在
Model.scoped
Model.all
中存在差异,即
scoped.scoped
返回一个范围,而
all.all
运行查询

在轨道3上:

> Model.scoped.scoped.is_a?(ActiveRecord::Relation)
=> true
在轨道4上:

> Model.all.all.is_a?(ActiveRecord::Relation)
DEPRECATION WARNING: Relation#all is deprecated. If you want to eager-load a relation, you can call #load (e.g. `Post.where(published: true).load`). If you want to get an array of records from a relation, you can call #to_a (e.g. `Post.where(published: true).to_a`).
=> false
库/关注点中有一些用例在有条件做某事或什么都不做时返回
范围
,例如:

module AmongConcern
  extend ActiveSupport::Concern

  module ClassMethods
    def among(ids)
      return scoped if ids.blank?

      where(id: ids)
    end
  end
end
如果您将此
作用域
更改为
所有
,您将面临随机问题,具体取决于在作用域链中使用了
中的
。例如,
Model.where(some:value).interferen(id)
将运行查询而不是返回范围

我想要的是
ActiveRecord::Relation
上的幂等方法,它只返回一个范围


我应该在这里做什么?

似乎
where(nil)
作用域的真正替代品,它在Rails 3和Rails 4上都有效:(

除了使用
where(nil)
之外,如果您知道
self
是一种关系,并且获得调用
scoped
的相同行为,没有参数,没有弃用警告,也可以调用
clone

编辑

我现在使用此代码作为
scoped
的替代品,因为我不喜欢在需要掌握当前作用域的任何地方使用
where(nil)

     # config/initializers/scoped.rb
     class ActiveRecord::Base
       # do things the modern way and silence Rails 4 deprecation warnings
       def self.scoped(options=nil)
         options ? where(nil).apply_finder_options(options, true) : where(nil)
       end
     end

我不明白为什么AR作者不能做类似的事情,因为正如OP所指出的,
all
scoped
的行为不一样。

正如其中一条评论中提到的,
all
应该返回一个范围

这些文档是正确的——它确实返回了ActiveRecord::Relation,但如果您想在控制台中看到它,则必须使用分号:

pry(main)> u = User.all;

pry(main)> u.class

=> ActiveRecord::Relation::ActiveRecord_Relation_User
在Rails 4.1(beta 1)中,以下工作:

Model.all.all.is_a?(ActiveRecord::Relation)
=> true

因此,这个问题似乎已经解决,在4.1.0
模型中,作用域
已全部删除。

您确定“
所有
都运行查询”吗东西不仅仅是一个人工制品控制台?建议它应该工作得很好。是的,我肯定。但是你没有得到警告,所以你从
范围/命名.rb中得到
所有的
是吧?而
范围/命名.rb中的
所有的
是,好了,什么
模型。所有的
都使用。哈?你不能调用
clone
在模型类上。(例如,
model.clone
scoped
在模型类和关系上都起作用。@kenn Yep,因此我在上面说“如果你知道self是一个关系”。弃用警告说使用
load
。如果你想急于加载,它说使用
load
,并且在任何情况下都需要一个参数(条件),因此到目前为止,
where(nil)
(或
true
{}
1
)似乎是
作用域
的最佳替代方案,但对我的情况不起作用:
user.active\u section.scoped.uniq(false)
user.active\u section.all.uniq(false)
user.active\u section.where(nil).uniq(false)
没有。rails 5呢?这与此无关-尝试
User.all.all;
,您会得到相同的警告。不幸的是,它直到rails 4.x甚至rails 5才会被修复。太好了,谢谢您的更新!但是如果您是gem维护者,您必须继续使用
where(nil)
直到4.0.x变得不受支持…这是一个非常旧的线程,但我们现在才升级,并且必须保持对Rails 3和4的支持。如果ActiveRecord::VERSION::MAJOR==3,然后Model.scoped else Model.all end,那么按照
的思路进行操作是否合理?