方法
实例公共方法
default_scopes?(all_queries: false) 链接
检查模型是否有任何默认范围。如果 all_queries 设置为 true,则该方法将检查模型是否有任何默认范围,其中 all_queries
为 true。
源代码:显示 | 在 GitHub 上
# File activerecord/lib/active_record/scoping/default.rb, line 62 def default_scopes?(all_queries: false) if all_queries self.default_scopes.any?(&:all_queries) else self.default_scopes.any? end end
unscoped(&block) 链接
返回模型的范围,不包含先前设置的范围。
class Post < ActiveRecord::Base
belongs_to :user
def self.default_scope
where(published: true)
end
end
class User < ActiveRecord::Base
has_many :posts
end
Post.all # Fires "SELECT * FROM posts WHERE published = true"
Post.unscoped.all # Fires "SELECT * FROM posts"
Post.where(published: false).unscoped.all # Fires "SELECT * FROM posts"
User.find(1).posts # Fires "SELECT * FROM posts WHERE published = true AND posts.user_id = 1"
User.find(1).posts.unscoped # Fires "SELECT * FROM posts"
此方法还接受一个块。块内的所有查询都不会使用先前设置的范围。
Post.unscoped {
Post.limit(10) # Fires "SELECT * FROM posts LIMIT 10"
}
源代码:显示 | 在 GitHub 上
# File activerecord/lib/active_record/scoping/default.rb, line 50 def unscoped(&block) block_given? ? relation.scoping(&block) : relation end
实例私有方法
default_scope(scope = nil, all_queries: nil, &block) 链接
在你的模型中使用这个宏来设置模型所有操作的默认范围。
class Article < ActiveRecord::Base
default_scope { where(published: true) }
end
Article.all
# SELECT * FROM articles WHERE published = true
该 default_scope
也在创建/构建记录时应用。它不会在更新或删除记录时应用。
Article.new.published # => true
Article.create.published # => true
要在你更新或删除记录时应用一个 default_scope
,请添加 all_queries: true
class Article < ActiveRecord::Base
default_scope -> { where(blog_id: 1) }, all_queries: true
end
将默认范围应用于所有查询将确保始终通过附加条件查询记录。请注意,只有 where 子句适用,因为在通过主键返回单个对象时添加 order 没有任何意义。
Article.find(1).destroy
# DELETE ... FROM `articles` where ID = 1 AND blog_id = 1;
(你也可以将任何响应于 call
的对象传递给 default_scope
宏,它将在构建默认范围时被调用。)
如果你在模型中使用多个 default_scope
声明,它们将被合并在一起。
class Article < ActiveRecord::Base
default_scope { where(published: true) }
default_scope { where(rating: 'G') }
end
Article.all
# SELECT * FROM articles WHERE published = true AND rating = 'G'
这在继承和模块包含中也是如此,其中父级或模块定义了一个 default_scope
,而子级或包含的类定义了第二个。
如果你需要对默认范围执行更复杂的操作,可以将其作为类方法定义。
class Article < ActiveRecord::Base
def self.default_scope
# Should return a scope, you can call 'super' here etc.
end
end
源代码:显示 | 在 GitHub 上
# File activerecord/lib/active_record/scoping/default.rb, line 129 def default_scope(scope = nil, all_queries: nil, &block) # :doc: scope = block if block_given? if scope.is_a?(Relation) || !scope.respond_to?(:call) raise ArgumentError, "Support for calling #default_scope without a block is removed. For example instead " \ "of `default_scope where(color: 'red')`, please use " \ "`default_scope { where(color: 'red') }`. (Alternatively you can just redefine " \ "self.default_scope.)" end default_scope = DefaultScope.new(scope, all_queries) self.default_scopes += [default_scope] end