ActiveRecord Rails 3 champ d'application vs méthode de classe
Je suis de nouveau à la nouvelle interface de requête de ActiveRecord, donc je suis encore de comprendre les choses.
J'espérais que quelqu'un pourrait expliquer la différence entre l'utilisation d'un scope
dans un ActiveRecord modèle et simplement à l'aide d'une méthode de classe (c'est à dire self.some_method
)
De ce que j'ai pu rassembler, un champ d'application devrait toujours retourner une relation, alors qu'une méthode de classe ne doit pas nécessairement. Est-ce vrai?
Par exemple, j'ai pensé qu'il serait judicieux de faire quelque chose comme:
class Person
scope :grouped_counts, group(:name).count
end
Mais cela ne fonctionne pas. J'obtiens cette erreur:
ArgumentError: Unknown key(s): communicating, failed, matched, unmatched
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/activesupport-3.0.5/lib/active_support/core_ext/hash/keys.rb:43:in `assert_valid_keys'
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/activerecord-3.0.5/lib/active_record/relation/spawn_methods.rb:110:in `apply_finder_options'
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/activerecord-3.0.5/lib/active_record/named_scope.rb:110:in `block in scope'
from (irb):48
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/railties-3.0.5/lib/rails/commands/console.rb:44:in `start'
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/railties-3.0.5/lib/rails/commands/console.rb:8:in `start'
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/railties-3.0.5/lib/rails/commands.rb:23:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
r
Il ne fait toutefois travailler en tant que méthode de classe
def self.grouped_counts
group(:name).count
end
Je suis intéressé de savoir des peuples pensées sur le moment d'utiliser des étendues et quand utiliser les méthodes de la classe. Suis-je raison de supposer qu'un champ doit toujours retourner une relation, mais une méthode de classe peut retourner ce qu'il veut?
Vous devez vous connecter pour publier un commentaire.
Il n'y avait plus de différence dans les Rails 2.x, depuis named_scopes ne pas exécuter vos requêtes (de sorte que vous pourriez chaîne d'eux), alors que les méthodes de la classe n'ont généralement exécuter les requêtes (si vous ne pouviez pas de la chaîne d'eux), à moins que vous manuellement enveloppé votre requête dans un
scoped(...)
appel.Dans Rails 3, tout retourne un
ActiveRecord::Relation
jusqu'à ce que vous avez besoin que les résultats réels, donc portées peuvent être enchaînés contre les méthodes de la classe et vice versa (aussi longtemps que les méthodes de la classe de rendementActiveRecord::Relation
objets, et non de quelque autre type d'objet (comme un nombre)).Généralement, j'utilise
scope
entrées pour un simple one-liners pour filtrer vers le bas de mon jeu de résultats. Cependant, si je fais rien de compliqué dans un "champ d'application", ce qui peut exiger détaillée de la logique, lambdas, sur plusieurs lignes, etc., Je préfère utiliser une méthode de classe. Et comme vous vous en pris, si j'ai besoin de revenir en compte ou quelque chose comme ça, j'utilise une méthode de classe.Comme Dylan fait allusion dans sa réponse, une différence entre la portée et la méthode d'une classe, c'est que les étendues sont évalués lorsque la classe est chargée. Ceci peut conduire à un résultat inattendu.
Par exemple,
est sujette à l'erreur. La bonne façon est d'utiliser une lambda
Lambda bloc est paresseusement évalué. Si La Date.aujourd'hui est exécuté lorsque vous appelez la portée, non
lorsque la classe est évaluée.
Si vous utilisez une méthode de classe, alors vous n'avez pas besoin d'utiliser lambda.
Parce que, avec la méthode de la classe, le code est exécuté au moment de l'appel de méthode.