J'ai une boucle (pour l'élément dans @dataset) et je veux, à chaque itération, obtenir des données différentes d'une autre table et effectuer certaines opérations qui seront imprimées dans la vue. Je ne peux pas obtenir ces données de l'ensemble de données utilisé dans la boucle.
Comment puis-je faire cela selon MVC? Je peux mettre le code dans la boucle, dans la vue, mais je pense que c'est horrible.
Dois-je utiliser un assistant pour cela et appeler la fonction depuis la vue?
Merci d'avance,
- ARemesal
Si vous avez une table et que vous souhaitez obtenir des données d'une autre table, c'est généralement le cas d'un has_many
relation. Par exemple, nous avons @people
(Person
modèle), et chaque personne has_many
adresses (modèle Address
). Dans ces cas, la meilleure chose à faire est la suivante:
# Controller
@people = Person.find(:all, :include => :addresses)
...
# View
@people.each do |p|
p.addresses.each do |address|
...
Si vos données ne sont pas uniquement des tables de base de données normales (peut-être que vous les obtenez à partir d'un service Web, etc.), alors une bonne chose à faire est de créer toutes les données dans le contrôleur à l'avance, puis de les transmettre à la vue . Quelque chose comme ça
# Controller
@people = Person.find(:all)
@people.each do |p|
# attach loaded data to the person object in controller
p.addresses = Address.load_from_somewhere_by_name(p.name)
...
De cette façon, le code d'affichage reste propre, comme ceci:
# View
@people.each do |p|
p.addresses.each do |address|
...
Si j'étais vous, je créerais une classe distincte qui encapsule l'ensemble de données et contient toute la logique impliquée dans le traitement des entrées de l'ensemble de données. Cette classe pourrait être itérable (répondez à chacun). Ensuite, je passais une instance de cette classe à la vue et n'utilisais que ses méthodes.
Person(id, name, other fields...)
Event(id, title, ...)
Date(id, date, time, event_id, ...)
Disponibility(id, percent, date_id, person_id, ...)
Bien sûr, toutes les relations sont définies dans le modèle.
J'ai une vue qui montre toutes les dates d'un événement, c'est facile. Mais je veux, pour chaque date, imprimer les données de toutes les personnes qui sont disponibles pour cette date. À mon avis, en oubliant le modèle de conception MVC, je pourrais coder quelque chose comme ceci:
<% for date in @Dates
available = Disponibility.find_by_date_id(date.id)
for item in available
guy = Person.find_by_id(item.person_id)
%>
Date de rendu et personnes disponibles ...
Je veux éviter cela dans la vue. Je pense que la réponse d'Orion Edwards est la plus proche de ce dont j'ai besoin, mais, dans cet exemple, l'adresse est un champ vide pour la table Personne? Ou comment puis-je ajouter un nouvel attribut à la classe Person?
Bien que je manque une astuce SQL pour ce faire?
Il est assez difficile de déterminer la meilleure solution à votre problème sans détails sur les données et les relations entre vos modèles (tableaux). L'idée commune est la suivante: gardez vos opinions stupides. Obtenez toutes les données nécessaires pour rendre la vue à l'intérieur de l'action de vos contrôleurs. Effectuez toutes les modifications et tous les calculs dans la même action. Ensuite, utilisez ces données en vue.
btw, si vous parlez d'un problème N + 1, lisez plus sur les paramètres ActiveRecord "include" et "join".
Vous auriez besoin d'expliquer davantage votre situation pour plus de réponse à ce sujet. Avec quel type d'opérations et d'autres modèles avez-vous besoin d'interagir? Si vous postez vos associations de modèles, je suis sûr que nous pourrions vraiment vous éloigner.
Bonne chance!