2008-11-11 9 views
25

J'ai une boucle (pour item dans @dataset) et je veux, à chaque itération, obtenir des données différentes d'une autre table et faire des 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.Rails: obtention de données à partir d'une table pour chaque itération d'une 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 à partir de la vue?

Nous vous remercions à l'avance,

- ARemesal

Répondre

42

Si vous avez une table et que vous voulez obtenir des données d'une autre table, cela se passe généralement dans une relation has_many. 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 ce

# Controller 
@people = Person.find(:all, :include => :addresses) 
... 

# View 
@people.each do |p| 
    p.addresses.each do |address| 
    ... 

Si vos données ne sont pas seulement des tables de base de données normale (peut-être vous l'obtenez à partir d'un service Web ou ainsi de suite), puis une bonne chose à faire est de construire tous les données dans le contrôleur à l'avance, puis passez cela à 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 de la vue reste propre, comme celui-ci:

# View 
@people.each do |p| 
    p.addresses.each do |address| 
    ... 
+0

Pour mes purpouses, je pense que c'est la meilleure solution. Merci Orion pour un conseil qui m'avait donné beaucoup de nouvelles idées :) – ARemesal

1

Il est très difficile de parler de la meilleure solution pour votre problème sans plus de détails sur les données et les relations entre vos modèles (tables). L'idée commune est la suivante: gardez vos opinions stupides. Obtenez toutes les données nécessaires pour afficher la vue dans l'action de vos contrôleurs. Faites tous les changements et les calculs dans la même action. Ensuite, en vue utiliser ces données.

btw, si vous parlez de problème N + 1, lisez en plus sur les paramètres 'include' et 'joins' ActiveRecord.

0
  • Gardez toute la logique de votre élément de @dataset dans l'action du contrôleur
  • utiliser des méthodes dans vos modèles pour l'interaction avec d'autres objets de modèle dont vous avez besoin
  • Vous devez être laissé avec seulement @dataset pour votre vue que vous pouvez rendre dans un partiel.

Vous auriez besoin d'expliquer votre situation pour plus de réponse à ce sujet. Quel genre 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 arranger.

Bonne chance!

1

Si j'étais vous je créerais une classe séparée qui encapsule l'ensemble de données et contient toute la logique impliquée dans le traitement des entrées de jeu de données. Cette classe pourrait être itérable (répondre à chacun). Ensuite, je passerais une instance de cette classe à la vue et utiliser seulement ses méthodes là.

+0

Je pense que c'est une bonne et jolie solution, mais c'est trop complexe pour mes besoins dans ce cas. Je vais l'annoter pour le futur :) – ARemesal

1
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 pour un événement, c'est facile. Mais je veux, pour chaque date, imprimer les données pour toutes les personnes disponibles pour cette date. À mon avis, oublier modèle de conception MVC, je pourrais code 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) 
%> 

Render date et les 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, address est un champ vide pour la table Person? Ou comment puis-je ajouter un nouvel attribut à la classe Person?

Bien, est-ce que je manque n'importe quel tour de SQL pour faire ceci?