views:

5497

answers:

5

Hi all there,

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?

Thank you in advance,

-- ARemesal

+1  A: 

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.

IDBD
A: 
  • Keep all the logic on your @dataset item inside the controller action
  • Utilize methods in your models for the interaction with other model objects you need
  • You should be left with only @dataset for your view that you can render in a partial.

You would need to further explain your situation for any more of answer on that. What kind of operations and other models do you need to interact with? If you post your model associations I'm sure we could really square you away.

Good luck!

mwilliams
+1  A: 

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.

Adam Byrtek
I think it's a good and pretty solution, but it's too complex for my needs in this case. I'll annotate it for the future :)
ARemesal
+9  A: 

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|
    ...
Orion Edwards
For my purpouses, I think this is the best solution. Thank you Orion for a tip what had given me a lot of new ideas :)
ARemesal
A: 

Thank you very much for your replies.

A simply view of my model:

Person(id, name, other fields...)
Event(id, title, ...)
Date(id, date, time, event_id, ...)
Disponibility(id, percent, date_id, person_id, ...)

Of course, all the relationships are defined in the Model.

I have a view that shows all the dates for a event, it's easy. But I want, for each date, to print the data for all the people whose are available for that date. In my view, forgetting MVC design pattern, I could code something like this:

<% 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 and people available...

I want to avoid this in the view. I think the Orion Edwards' answer is the nearest for what I need, but, in that example, address is an empty field for Person table? Or how can I append a new attribute to Person class?

Although, am I missing any SQL trick for do this?

ARemesal