113 votes

Qu'est-ce que le scope/named_scope in rails?

J'ai récemment commencé un stage. Mon employeur utilise ruby on rails, et je rencontre fréquemment de nouvelles syntaxes que je dois chercher pour comprendre. J'ai cherché sur Google une bonne explication de named_scope, mais ce que j'ai trouvé jusqu'à présent est principalement des articles de blog le louant, plutôt qu'une définition ou une introduction claire.

Qu'est-ce que named_scope (maintenant simplement appelé scope) en ruby on rails exactement?

0 votes

2 votes

Ce billet de blog m'a été très précieux lors de l'apprentissage des portées nommées : ryandaigle.com/articles/2008/8/20/…

1 votes

@notapatch le lien est mort, en auriez-vous un autre ?

220voto

Une portée est un sous-ensemble d'une collection. Cela semble compliqué ? Ce n'est pas le cas. Imaginez ceci :

Vous avez des Utilisateurs. Maintenant, certains de ces Utilisateurs sont abonnés à votre bulletin d'information. Vous avez marqué ceux qui reçoivent un bulletin d'information en ajoutant un champ à la base de données des Utilisateurs (user.subscribed_to_newsletter = true). Naturellement, vous voulez parfois obtenir ces Utilisateurs qui sont abonnés à votre bulletin d'information.

Vous pourriez, bien sûr, toujours faire ceci :

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

Au lieu d'écrire cela tout le temps, vous pourriez cependant faire quelque chose comme ceci.

#Fichier: users.rb
class User < ActiveRecord::Base
  scope :newsletter, where(subscribed_to_newsletter: true)
  #bla bla

Si vous utilisez Rails 4 ou plus récent, faites ceci à la place :

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

Cela vous permet d'accéder à vos abonnés en faisant simplement ceci :

User.newsletter.each do #quelquechose

Ceci est un exemple très simple mais en général, les portées peuvent être des outils très puissants pour faciliter votre travail.

Consultez ce lien : Description de l'API

7 votes

Est-ce que je peux demander quels sont les avantages de ceci par rapport à dire la définition d'une méthode dans la classe Utilisateur appelée 'UtilisateursAbonnés'? par ex. 'def self.utilisateursAbonnés self.where(:abonné_à_la_newsletter => true) end

3 votes

@redroot l'avantage est que la syntaxe scope est beaucoup plus propre, vous obtenez le même résultat mais avec juste une ligne.

11 votes

@redroot Il y avait autrefois un énorme avantage en termes d'efficacité, car les scopes interrogeaient la base de données de manière paresseuse tandis que les méthodes le faisaient de manière proactive. Dans Rails 3, les méthodes sont également devenues paresseuses, donc maintenant la différence est plus syntaxique. Source

34voto

Akshatha Points 11

Scope dans active record est comme des méthodes de classe mais elles retournent un objet Relation, ce qui signifie que vous pouvez appeler un autre scope ou une méthode de requête active record dessus.

Par exemple, si vous avez un modèle Zombie (table zombies) avec les méthodes de scope mentionnées ci-dessous,

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

Et vous appelez

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

Cela se traduit par le SQL ci-dessous,

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

L'exemple ci-dessus est basé sur la syntaxe de rails 4

0 votes

Je ne trouve pas d'exemple de order(:created_at, :desc) dans toute documentation. Est-il possible que vous vouliez dire scope :recent, -> { order(created_at: :desc) } ? apidock.com/rails/v4.2.9/ActiveRecord/QueryMethods/order

8voto

Imran Ahmad Points 4242

Les scopes ne sont rien d'autre que des méthodes de classe.

Pourquoi les utiliser?

Le scoping vous permet de spécifier des requêtes couramment utilisées (cela peut être considéré comme un raccourci pour les requêtes longues ou les plus fréquemment utilisées) qui peuvent être référencées comme des appels de méthode sur les objets d'association ou les modèles. Avec ces scopes, vous pouvez utiliser toutes les méthodes précédemment couvertes telles que where, joins et includes. Toutes les méthodes de scope retourneront un objet ActiveRecord::Relation qui permettra d'appeler d'autres méthodes (comme d'autres scopes) dessus.

Pour définir un scope simple, nous utilisons la méthode scope à l'intérieur de la classe, en passant la requête que nous aimerions exécuter lorsque ce scope est appelé:

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

C'est exactement la même chose que de définir une méthode de classe, et celui que vous utilisez dépend de vos préférences personnelles:

class Article < ActiveRecord::Base
  def self.published
    where(published: true)
  end

Veuillez suivre le lien suivant pour une description complète avec exemple. J'espère que cela vous aidera.

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

3 votes

Ce n'est pas exactement la même chose que de définir une méthode de classe. Les méthodes de classe renvoient nil dans quelques cas, et ne sont donc pas chaînables pour certaines conditions.

7voto

123 Points 149

La meilleure façon de comprendre les détails est de consulter la documentation de l'API.

Vous obtiendrez les détails complets et les façons dont nous pouvons utiliser les Scopes.

Documentation de l'API sur les Scopes

1voto

BKSpurgeon Points 11129
  • Imaginez que vous avez un modèle: Personne.

Maintenant, imaginez que vous :

  • voulez toutes les personnes dans le monde qui ont les cheveux roux.
  • voulez toutes les personnes dans le monde qui jouent au cricket

Vous pourriez obtenir ces classes particulières de personnes en utilisant une portée !

Personne.cheveux_roux.cricket ## trouve toutes les personnes aux cheveux roux qui jouent au cricket
Personne.cheveux_roux ## trouve toutes les personnes aux cheveux roux
Personne.cricket ## trouve toutes les personnes qui jouent au cricket.

Maintenant, ce n'était pas si difficile, n'est-ce pas ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X