Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: getting data from a table for each iteraction of a loop

I have a loop (for item in @dataset) and I want, in each iteration, to get different data from another table and make some operations that will be printed in the view. I cant't get this data from the dataset used in the loop.

How can I do this according to MVC? I can put the code into the loop, in the view, but I think it's horrible.

Must I use a helper for do this, and call the function from the view?

like image 399
ARemesal Avatar asked Nov 11 '08 15:11

ARemesal


3 Answers

If you have one table, and want to get data from another table, usually this is in the situation of a has_many relation. For example, we have @people (Person model), and each person has_many addresses (Address model). In those cases the best thing to do is this

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

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

If your data is not just normal database tables (maybe you get it from a web service or so on), then a good thing to do is to build all the data in the controller ahead-of-time, then pass that to the view. Something like this

# 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)
...

This way the view code stays clean, like this:

# View
@people.each do |p|
  p.addresses.each do |address|
    ...
like image 105
Orion Edwards Avatar answered Nov 05 '22 15:11

Orion Edwards


It is quite hard to tell about best solution for your problem without details about data and relations between your models(tables). The common idea is next: keep your views stupid. Get all data needed to render view inside your controllers action. Make all changes and calculations inside same action. Then in view use this data.

btw, if you are talking about N+1 problem then read more about 'include' and 'joins' ActiveRecord parameters.

like image 1
IDBD Avatar answered Nov 05 '22 17:11

IDBD


If I was you I would create a separate class that encapsulates the dataset and contains all the logic involved in processing the dataset entries. This class could be iterable (respond to each). Then I would pass an instance of this class to the view and use only its methods there.

like image 1
Adam Byrtek Avatar answered Nov 05 '22 16:11

Adam Byrtek