在 Rail 中 scope/name_scope 是什么?

我最近刚开始实习。我的老板使用 ruby on ails,我经常遇到需要查阅才能理解的新语法。我到处搜索关于 name _ scope 的解释,但是到目前为止,我发现大多数博客文章都对它给予了高度赞扬,而不是一个直接的定义或介绍。

在 ruby on ails 中,究竟什么是名为 _ scope (现在简称 scope)的?

54146 次浏览

A scope is a subset of a collection. Sounds complicated? It isn't. Imagine this:

You have Users. Now, some of those Users are subscribed to your newsletter. You marked those who receive a newsletter by adding a field to the Users Database (user.subscribed_to_newsletter = true). Naturally, you sometimes want to get those Users who are subscribed to your newsletter.

You could, of course, always do this:

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

Instead of always writing this you could, however, do something like this.

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

If you're using Rails 4 or newer, do this instead:

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

This allows you to access your subscribers by simply doing this:

User.newsletter.each do #something

This is a very simple example but in general scopes can be very powerful tools to easy your work.

Check out this link: API Description

The best way to understand about the details is to go to API Documentation.

You'll get the complete details and the ways we can use Scopes.

API Documentation of Scope

scope in active record is like class methods but they return Relation object which means you can call another scope or active record querying method on it.

For example, if you have a Zombie model (zombies table) with below mentioned scope methods,

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

And you call

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

It translates to the below in SQL,

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

Example above is based on rails 4 syntax

  • Imagine you have a model: Person.

Now imagine you :

  • want all the people in the world who have red hair.
  • want all the people in the world who play cricket

You could get those particular classes of people by using a scope!

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.

Now that wasn't so hard was it?