2008-11-11 11 views
25

Tengo un bucle (para el elemento en @dataset) y quiero, en cada iteración, obtener datos diferentes de otra tabla y realizar algunas operaciones que se imprimirán en la vista. No puedo obtener estos datos del conjunto de datos utilizado en el ciclo.Rieles: obtener datos de una tabla para cada iteración de un bucle

¿Cómo puedo hacer esto de acuerdo con MVC? Puedo poner el código en el bucle, en la vista, pero creo que es horrible.

¿Debo usar un ayudante para hacer esto y llamar a la función desde la vista?

gracias de antemano,

- ARemesal

Respuesta

42

Si tiene una tabla, y quiere obtener datos de otra tabla, por lo general esto está en la situación de una relación has_many. Por ejemplo, tenemos @people (modelo Person), y cada persona has_many direcciones (modelo Address). En esos casos, lo mejor que puede hacer es esto

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

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

Si los datos son no sólo las tablas de bases de datos normales (tal vez la recibe de un servicio web o así sucesivamente), entonces una buena cosa que hacer es construir todo los datos en el controlador antes de tiempo, luego pasa eso a la vista. Algo como esto

# 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 esta manera el código de la vista se mantiene limpio, así:

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

Para mis propósitos, creo que esta es la mejor solución. Gracias a Orion por un consejo que me ha dado muchas ideas nuevas :) – ARemesal

1

Es muy difícil saber acerca de la mejor solución para su problema sin detalles acerca de los datos y las relaciones entre sus modelos (tablas). La idea común es la siguiente: mantén tus puntos de vista estúpidos. Obtenga todos los datos necesarios para mostrar la vista dentro de la acción de su controlador. Haga todos los cambios y cálculos dentro de la misma acción. Entonces a la vista usa esta información.

Por cierto, si está hablando de un problema N + 1, lea más acerca de los parámetros 'incluir' y 'une' a ActiveRecord.

0
  • mantener toda la lógica en su artículo @dataset dentro de la acción del controlador
  • utilizar métodos en sus modelos para la interacción con otro modelo de objetos que necesita
  • Usted debe quedar sólo con @dataset para la vista que puedes renderizar de forma parcial.

Debería explicar su situación para obtener más respuestas sobre eso. ¿Con qué tipo de operaciones y otros modelos necesita interactuar? Si publicas las asociaciones de tu modelo, estoy seguro de que podríamos distanciarte.

¡Buena suerte!

1

Si yo fuera usted, crearía una clase separada que encapsule el conjunto de datos y contenga toda la lógica involucrada en el procesamiento de las entradas del conjunto de datos. Esta clase podría ser iterable (responder a cada uno). Luego pasaría una instancia de esta clase a la vista y usaría solo sus métodos allí.

+0

Creo que es una solución buena y bonita, pero es demasiado compleja para mis necesidades en este caso. Voy a anotarlo para el futuro :) – ARemesal

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

Por supuesto, todas las relaciones están definidas en el modelo.

Tengo una vista que muestra todas las fechas de un evento, es fácil. Pero quiero, para cada fecha, imprimir los datos de todas las personas que están disponibles para esa fecha. En mi opinión, olvidando patrón de diseño MVC, podría codificar algo como esto:

<% for date in @Dates 
    available = Disponibility.find_by_date_id(date.id) 
    for item in available 
    guy = Person.find_by_id(item.person_id) 
%> 

fecha y la gente disponible Render ...

quiero evitar esto en la vista. Creo que la respuesta de Orion Edwards es la más cercana para lo que necesito, pero, en ese ejemplo, ¿la dirección es un campo vacío para la tabla Person? ¿O cómo puedo agregar un nuevo atributo a la clase Person?

Aunque, ¿me falta algún truco de SQL para hacer esto?

Cuestiones relacionadas