Y a-t-il un moyen de trouver tous les modèles polymorphes d'un type polymorphe spécifique dans des rails? Donc, si j'ai le groupe, l'événement et le projet avec une déclaration comme: p>
Puis-je faire quelque chose comme: p>
... ou p>
Ce serait bien. P>
EDIT: P>
... tel que has_many: assignations ,: as =>: Assignable code> p>
assignable.all code> p>
intégréRailsPolymorphichelper.all ("assignable") code> p>
assignable.all code> renvoie
[événement, groupe, produit] code> (tableau de classes) p>
5 Réponses :
Vous devriez pouvoir simplement utiliser la collection associée:
Cela retournera tous les attributions code> pour une instance de modèle. Je pense qu'il veut retourner tous les affectations
code> pour un type.
Mais vous ne pouvez pas simplement dire événement.Assiffrents.all?
Rails n'ajoute pas d'assistants de l'association statique. Donc événement.Assignments code> lancera
nométhoderror code>.
Il n'y a pas de méthode directe pour cela. J'ai écrit ce patch de singe pour activerecord :: base code>.
Cela fonctionnera pour n'importe quelle classe.
Assignable.all_polymorphic_types(:assignable).map(&:to_s)
# returns ['Project', 'Event', 'Group']
Comment puis-je implémenter cela? Est-ce que je vais à la classe aciverecord :: base à modifier? Je ne peux pas sembler trouver cette classe dans mon projet ..
@James Reportez-vous à cette réponse: Stackoverflow.com/Questtions/2328984/ ...
C'est beau! N'a-t-il pas un moyen d'éviter d'avoir à ouvrir les fichiers code> modèle code>? Ne les rails ne connaît pas déjà toutes les classes?
@Augustinriedinger dans le mode de produit que vous pouvez utiliser activerecord :: base.subclasses code>, en mode Dev, les classes sont chargées uniquement après leur référence explicitement. Donc, ce n'est pas trop fiable. Mon approche lit les noms de fichiers (pas le contenu) et il est fait une fois pour la durée de vie du processus. Donc, il est tolérable ..
Ouais je le google aussi. Le fait qu'il soit lu qu'une seule fois le rend acceptable en effet. Mais il serait même plus agréable qu'il charge au démarrage au lieu d'un appel au premier appel parce que le premier est réellement beaucoup plus lent ...
@Augustinriedinger, vous pouvez ajouter un fichier d'initialisateur ( config / initialiseurs / actif_record.rb code>) à votre projet et appelez
activerecord :: base. all_polymorphic_types ('foo') code> en elle.
Oui, mais je voulais dire pour toute la Classe. Ce qui signifie que l'ouverture du dossier code> modèles code>, sauf si elle est chargée au début.
@Augustinrieinger Calling Activerecord :: base. all_polymorphic_types code> charge toutes les classes.
Impressionnant. Cela devrait vraiment faire partie de AR lui-même. Énormément utile par exemple pour la construction de formes.
J'ai créé une classe de modèle polymorphe avec une méthode 'all' pour tester cela. Voici ma configuration de l'application: P> User < ActiveRecord::Base
belongs_to :profile, :polymorphic => true
end
Student < ActiveRecord::Base
has_one :user, :as => :profile
end
Pour obtenir ce travail dans le développement Enviroment, vous devez exiger les fichiers de modèles.
Ceci est une classe spéciale, ne descend pas d'ActionCord.
Vous pouvez également essayer de cette façon. Casser au-dessus de la solution ne fonctionne pas pour moi parce que j'ai eu du modèle de Mongo.
get_has_many_associations_for_model("assignments", "assignable")
La solution HARRISH SHETTY ne fonctionnera pas pour les fichiers de modèlePachets qui ne sont pas stockés directement dans Rails.root / app / modèles mais dans un sous-répertoire. Bien qu'il gobe correctement des fichiers dans les sous-répertoires, il ne parvient pas à inclure le sous-répertoire lors du changement de nom de fichier en une constante. La raison en est que le sous-rédirateur de noms de noms est supprimé par cette ligne:
def self.all_polymorphic_types(name) @poly_hash ||= {}.tap do |hash| Dir.glob(File.join(Rails.root, "app", "models", "**", "*.rb")).each do |file| file.sub!(File.join(Rails.root, "app", "models"), '') file.sub!('.rb', '') klass = file.classify.constantize rescue nil next unless klass.ancestors.include?(ActiveRecord::Base) klass. reflect_on_all_associations(:has_many). select{ |r| r.options[:as] }. each do |reflection| (hash[reflection.options[:as]] ||= []) << klass end end end @poly_hash[name.to_sym] end
J'ai changé ma réponse en fonction des informations supplémentaires que vous avez données. Je pense que cela traitera de votre besoin.