Comment peut-on ActiveRecord::Relation objet d'appeler les méthodes de la classe
Comment un ActiveRecord::Relation objet d'appeler les méthodes de la classe?
class Project < ActiveRecord::Base
has_many :tasks
end
class Task < ActiveRecord::Base
belongs_to :project
def self.initial_tasks # class methods
# here return initial tasks
end
end
Maintenant, nous pouvons appeler :
Project.first.tasks.initial_tasks # how it works
initial_tasks
est une méthode de classe, et nous ne pouvons pas appeler les méthodes de la classe sur un objet.
Project.first.tasks
retourne un ActiveRecord::Relation d'objet, alors comment pourrait-il être en mesure d'appeler initial_tasks
?
Veuillez expliquer.
- Je suis un peu confus. Votre méthode est le nom de l'auto.initial_tasks, mais vous êtes d'appel .initial_task? Laquelle est la bonne?
- désolé sa "initial_tasks".
- Un peu de chance avec cette mesure?
Vous devez vous connecter pour publier un commentaire.
Il n'y a pas beaucoup de documentation sur l'application sur les méthodes de la classe à
ActiveRecord::Relation
objets, mais nous pouvons comprendre ce problème en prenant un oeil à la façon dont ActiveRecord étendues travail.Première, Rails de modèle portée sera de retour une
ActiveRecord::Relation
objet. À partir de la documentation:Tout d'abord, l'invocation d'une portée retourne un
ActiveRecord::Relation
objet:Ensuite, vous pouvez faire fonctionner l'
ActiveRecord::Relation
objet à l'aide du modèle de méthodes de la classe:C'est un peu un rond-point de la voie de la compréhension de la relation entre les méthodes de la classe et
ActiveRecord::Relation
, mais l'essentiel est ceci:ActiveRecord::Relation
objetsActiveRecord::Relation
objets ont accès à des méthodes de la classeIl est extrêmement facile à explorer. Vous venez de faire:
Alors appel
Project.first.tasks.initial_tasks
et vous obtenez:Et que vous n'avez pas besoin en fait. Facile à explorer, mais pas si facile à comprendre.
Maintenant, je vais vous expliquer ce que cela signifie.
Lorsque vous appelez
Project#tasks
méthode il ne pas retour vous ActiveRecord::Relation d'objet. En fait, il vous renvoie une instance de l'exécution, créé classe nommée Tâche::ActiveRecord_Associations_Collectionproxy hérité de ActiveRecord::Associations::CollextionProxy qui à son tour hérité de ActiveRecord::Relation. Ce runtime-catégorie est liée à la Tâche de la classe et contient de façon dynamique-définis (via method_missing proxy-méthodes de déléguer des appels à la Tâche les méthodes de la classe et de fusion portée association avec la classe-définition du champ d'application retournés par les méthodes de la classe.Comment ça marche (vraiment non-trivial):
ActiveRecord::Délégation::DelegateCache module ici.
DelegateCache a
DelegateCache.inherited
de rappel qui définit@relation_delegate_cache
attribut à chaque fois que vous héritez d'ActiveRecord::Base. Il désigne l'ensemble AR::Base descendant les classes ont un tel attribut. Le rappel appelsDelegateCache#initialize_relation_delegate_cache
méthode qui, dans l'ordre remplit cache attribut avec l'exécution créé des classes:Ici ces classes d'obtenir des noms inhabituels à la
Task::ActiveRecord_Associations_CollectionProxy
mentionné plus tôt.
#initial_tasks
surProject.tasks
). Sur cet appel, il définit de manière dynamique nouveau runtime-classe de méthodes d'instance délégué aux méthodes de la classe. Maintenant, vous avez une Tâche de classe liée à la Tâche::ActiveRecord_Associations_Collectionproxy classe contenant tous les niveau de l'instance méthodes proxy appels à la Tâche méthodes de la classe obtenir portée de résultat et de le fusionner avec l'association actuelle portée (ici).Que l'AR préfère dynamiquement les méthodes définies sur l'exécution créé des classes sur l'utilisation inefficace method_missing appels sur ActiveRecord::Relation.
Je pense que c'est OK si vous ne comprenez pas du tout ce genre de choses. Viens d'appeler les méthodes de la classe sur les associations 🙂
Project#task
n'est pas unActiveRecord::Relation
. En outre, les méthodes de la classe d'un ActiveRecord modèle ne sont pas seulement disponibles pour les associations, mais également à ses propres relations ou étendues. Mais je pense que le fait d'avoir "accès" de ces méthodes est le même que vous avez décrite ci-dessus 🙂 Merci, sera mise à jour bientôt.Ici dans ActiveRecord::la Relation, la Relation est représentant l'ensemble de la table
et votre Post de classe est la carte avec table,
Donc ActiveRecord::Rapport de tableau ou d'un enregistrement unique, il peut accéder à la méthode de classe.