rails中的scope / named_scope是什么?

时间:2011-02-02 01:42:47

标签: ruby-on-rails named-scope

我最近开始实习。我的雇主在轨道上使用ruby,我经常遇到我需要了解的新语法。我已经用Google搜索了对named_scope的一个很好的解释,但到目前为止我发现的主要是博客帖子,对它给予了高度赞扬,而不是直接的定义或介绍。

在轨道上的红宝石中究竟是什么名称_scope(现在简称为范围)?

5 个答案:

答案 0 :(得分:184)

范围是集合的子集。听起来很复杂?事实并非如此。想象一下:

你有用户。现在,其中一些用户订阅了您的简报。您通过向用户数据库添加字段(user.subscribed_to_newsletter = true)来标记收到新闻稿的人。当然,您有时希望获得订阅您的简报的用户。

当然,你可以这样做:

User.where(subscribed_to_newsletter: true).each do #something

然而,不是总是写这个,你可以这样做。

#File: users.rb
class User < ActiveRecord::Base
  scope :newsletter, where(subscribed_to_newsletter: true)
  #yada yada
end

如果您使用 Rails 4或更新版,请改为:

#File: users.rb
class User < ActiveRecord::Base
  scope :newsletter, -> { where(subscribed_to_newsletter: true) }
  #yada yada
end

这样,您只需执行以下操作即可访问您的订阅者:

User.newsletter.each do #something

这是一个非常简单的示例,但一般情况下,范围可以是非常强大的工具,以方便您的工作。

点击此链接:API Description

答案 1 :(得分:26)

活动记录中的作用域类似于类方法,但它们返回Relation对象,这意味着您可以在其上调用另一个作用域或活动记录查询方法。

例如,如果你有一个带有下面提到的范围方法的Zombie模型(僵尸表),

class Zombie
  scope :rotting, -> { where(rotting: true) }
  scope :fresh, -> { where('age < ?', 25) }
  scope :recent, -> { order(:created_at, :desc) }
end

你打电话

Zombie.rotting.fresh.recent.limit(3)

它转换为SQL中的以下内容,

select "zombies.*" from "zombies" where "zombies"."rotting" = 't' and (age<20) order by create_at desc limit 3

上面的示例基于rails 4 syntax

答案 2 :(得分:7)

了解详细信息的最佳方式是转到API文档。

您将获得完整的详细信息以及我们使用Scopes的方式。

API Documentation of Scope

答案 3 :(得分:7)

  

范围只是类方法。

为什么要使用它们?

作用域允许您指定常用查询(可以将其视为长或最常用查询的快捷方式),可以将其作为对关联对象或模型的方法调用进行引用。使用这些范围,您可以使用之前涵盖的每种方法,例如where,joins和includes。所有范围方法都将返回一个ActiveRecord :: Relation对象,这将允许在其上调用更多方法(例如其他范围)。

要定义一个简单的作用域,我们在类中使用scope方法,传递我们想要在调用此作用域时运行的查询:

$ mysql 
mysql> SELECT Host,user FROM mysql.user WHERE `Host` LIKE 'IP';

这与定义类方法完全相同,您使用的是个人偏好:

class Article < ActiveRecord::Base
  scope :published, -> { where(published: true) }
end

请通过以下链接获取完整说明并附带示例。我希望这会对你有所帮助。

http://guides.rubyonrails.org/active_record_querying.html

答案 4 :(得分:1)

  • 想象一下你有一个模特:

现在想象一下:

  • 希望世界上所有红头发的人。
  • 希望世界上所有打板球的人

你可以通过使用范围来获得那些特定类别的人!

Person.red_hair.cricket ## finds all people with red hair who play cricket
Person.red_hair ## finds all people with red hair
Person.cricket ## finds all people who play cricket.

现在那不是很难吗?