J'ai récemment commencé un stage. Mon employeur utilise Ruby on Rails, et je rencontre fréquemment de nouvelles syntaxes que je dois rechercher pour comprendre. J'ai cherché sur Google pour une bonne explication de named_scope, mais ce que j'ai trouvé loin est principalement des articles de blog qui en font l'éloge, plutôt une définition ou une introduction directe.
Quel est exactement named_scope (maintenant simplement appelé scope) dans Ruby on rails?
Une étendue est un sous-ensemble d'une collection. Cela semble compliqué? Ce n'est pas le cas. Imagine ça:
Vous avez des utilisateurs. Maintenant, certains de ces utilisateurs sont abonnés à votre newsletter. Vous avez marqué ceux qui reçoivent une newsletter en ajoutant un champ à la base de données des utilisateurs (user.subscribed_to_newsletter = true). Naturellement, vous souhaitez parfois obtenir les utilisateurs qui sont abonnés à votre newsletter.
Vous pouvez bien sûr toujours faire ceci:
User.where(subscribed_to_newsletter: true).each do #something
Au lieu de toujours écrire cela, vous pouvez cependant faire quelque chose comme ça.
#File: users.rb
class User < ActiveRecord::Base
scope :newsletter, where(subscribed_to_newsletter: true)
#yada yada
end
Si vous utilisez Rails 4 ou plus récent , faites-le à la place:
#File: users.rb
class User < ActiveRecord::Base
scope :newsletter, -> { where(subscribed_to_newsletter: true) }
#yada yada
end
Cela vous permet d'accéder à vos abonnés simplement en procédant comme suit:
User.newsletter.each do #something
Il s'agit d'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
la portée dans l'enregistrement actif est similaire aux méthodes de classe, mais elles renvoient un objet Relation, ce qui signifie que vous pouvez appeler une autre portée ou une méthode de requête d'enregistrement actif dessus.
Par exemple, si vous avez un modèle Zombie (table zombies) avec les méthodes d'étendue mentionnées ci-dessous,
class Zombie
scope :rotting, -> { where(rotting: true) }
scope :fresh, -> { where('age < ?', 25) }
scope :recent, -> { order(:created_at, :desc) }
end
Et tu appelles
Zombie.rotting.fresh.recent.limit(3)
Cela se traduit par ci-dessous en SQL,
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 Rails 4
La meilleure façon de comprendre les détails est d'aller à la documentation de l'API.
Vous obtiendrez les détails complets et les façons dont nous pouvons utiliser les étendues.
Les étendues ne sont que des méthodes de classe.
Pourquoi les utiliser?
La portée vous permet de spécifier les requêtes couramment utilisées (il 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 ou modèles d'association. Avec ces étendues, vous pouvez utiliser toutes les méthodes précédemment couvertes, telles que où, les jointures et les inclusions. Toutes les méthodes d'étendue renverront un objet ActiveRecord :: Relation qui permettra d'appeler d'autres méthodes (telles que d'autres étendues).
Pour définir une portée simple, nous utilisons la méthode scope à l'intérieur de la classe, en passant la requête que nous aimerions exécuter lorsque cette portée est appelée:
class Article < ActiveRecord::Base
scope :published, -> { where(published: true) }
end
C'est exactement la même chose que la définition d'une méthode de classe, et que vous utilisez est une question de préférence personnelle:
class Article < ActiveRecord::Base
def self.published
where(published: true)
end
end
Veuillez suivre le lien suivant pour une description complète avec un exemple. J'espère que cela t'aidera.
Imaginez-vous maintenant:
Vous pourriez obtenir ces classes particulières de personnes en utilisant une portée!
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.
Maintenant, ce n'était pas si difficile, n'est-ce pas?