2008-11-11 14 views
25

Mam pętlę (dla pozycji w @dataset) i chcę, aby w każdej iteracji uzyskać różne dane z innej tabeli i wykonać pewne operacje, które zostaną wydrukowane w widoku. Nie mogę uzyskać tych danych z zestawu danych użytego w pętli.Szyny: pobieranie danych z tabeli dla każdej iteracji pętli

Jak mogę to zrobić zgodnie z MVC? Mogę umieścić kod w pętli w widoku, ale myślę, że to okropne.

Czy w tym celu należy użyć helpera i wywołać funkcję z widoku?

Dziękuję z góry,

- ARemesal

Odpowiedz

42

Jeśli masz jedną tabelę i chcesz pobrać dane z innej tabeli, zwykle jest to w sytuacji relacji has_many. Na przykład mamy model @people (Person), a każda osoba has_many adresów (model Address). W takich przypadkach najlepszym rozwiązaniem jest to

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

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

Jeśli dane nie jest po prostu normalne tabele bazy danych (może go pobrać z serwisu WWW lub tak dalej), to jest dobrą rzeczą do zrobienia jest, aby zbudować wszystko dane w kontrolerze z wyprzedzeniem, a następnie przekazać je do widoku. Coś takiego

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

ten sposób kod widok pozostaje czysty, tak:

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

Dla moich celów, uważam, że jest to najlepsze rozwiązanie. Dziękuję Orionowi za podpowiedź, która dała mi wiele nowych pomysłów :) – ARemesal

1

Trudno jest mówić o najlepsze rozwiązanie problemu bez informacji o danych i relacji między swoimi modeli (tabelach). Wspólny pomysł jest następujący: zachowaj głupie poglądy. Uzyskaj wszystkie dane potrzebne do renderowania widoku w działaniu kontrolerów. Dokonaj wszystkich zmian i obliczeń w tej samej akcji. Następnie użyj tych danych.

btw, jeśli mówisz o problemie N + 1, przeczytaj więcej o parametrach "Dołącz" i "dołącza" do ActiveRecord.

0
  • zachować wszystkie logiki na swojej pozycji @dataset wewnątrz działania kontrolera
  • wykorzystują metody w modelach dla interakcji z innym modelem obiektów trzeba
  • Należy pozostawić tylko @dataset do widzenia można renderować w częściowym.

Będziesz musiał dokładniej wyjaśnić swoją sytuację, aby uzyskać więcej odpowiedzi na ten temat. Z jakimi operacjami i innymi modelami potrzebujesz interakcji? Jeśli opublikujesz swoje skojarzenia modelowe, jestem pewien, że naprawdę moglibyśmy Cię oddzielić.

Powodzenia!

1

Gdybym był tobą, utworzyłbym oddzielną klasę, która hermetyzuje zbiór danych i zawiera całą logikę związaną z przetwarzaniem wpisów zestawu danych. Ta klasa może być iterowalna (odpowiedź na każdą). Następnie przekazałbym instancję tej klasy do widoku i używałbym tam tylko jej metod.

+0

Myślę, że to dobre i ładne rozwiązanie, ale w tym przypadku jest ono zbyt skomplikowane dla moich potrzeb. Opiszę to na przyszłość :) – ARemesal

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

Oczywiście, wszystkie relacje są zdefiniowane w modelu.

Mam widok, który pokazuje wszystkie daty wydarzenia, to proste. Ale chcę, dla każdej daty, wydrukować dane dla wszystkich osób, które są dostępne dla tej daty. Moim zdaniem, zapominając wzorca projektowego MVC, mogę kodować coś takiego: datę i ludzi wolnych

<% 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 ...

Chcę tego uniknąć w widoku. Myślę, że odpowiedź Oriona Edwardsa jest najbliższa temu, czego potrzebuję, ale w tym przykładzie adres jest pustym polem dla tabeli Person? Albo w jaki sposób mogę dodać nowy atrybut do klasy Person?

Chociaż brakuje mi jakiejkolwiek sztuczki SQL, aby to zrobić?

Powiązane problemy