Activerecord 对于Rails 4,Model.scoped不推荐使用,但是Model.all可以';我不能替换它
起始Rails 4,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
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,那么按照的思路进行操作是否合理?