2010-02-11 16 views
8

Pracuję nad aplikacją, która ma kilka różnych modeli (bilety, posty, raporty itp.). Dane są różne w każdym modelu i chcę utworzyć "kanał" ze wszystkich modeli, które wyświetlają 10 najnowszych wpisów na tablicy (połączenie wszystkich danych).Tworzenie "kanałów" z wielu różnych modeli Railsów

Jaki jest najlepszy sposób na rozwiązanie tego problemu? Czy powinienem utworzyć nowy model kanału i napisać do tej tabeli, gdy użytkownikowi zostanie przypisany bilet lub zostanie opublikowany nowy raport? Badaliśmy również STI, aby zbudować tabelę odniesień do modelu lub po prostu stworzyć metodę klasy, która agreguje dane. Nie wiem, która metoda jest najbardziej wydajna ...

Odpowiedz

6

Ty może to zrobić na dwa sposoby w zależności od wymagań wydajnościowych.

Im mniej skuteczną metodą jest pobranie 10 * N przedmioty i sortować i zmniejszyć wymagane:

# Fetch 10 most recent items from each type of object, sort by 
# created_at, then pick top 10 of those. 
@items = [ Ticket, Post, Report ].inject([ ]) do |a, with_class| 
    a + with_class.find(:all, :limit => 10, :order => 'created_at DESC') 
end.sort_by(&:created_at).reverse[0, 10] 

Innym sposobem jest stworzenie tabeli indeksu, który ma polimorficzny skojarzenia z różnych rekordów. Jeśli zależy Ci tylko na wyświetlaniu 10 na raz, możesz agresywnie przycinać to za pomocą pewnego rodzaju zadania rake, aby ograniczyć go do 10 na użytkownika lub jakikolwiek zakres jest wymagany.

+0

To działa dobrze i wydaje się poruszać dość szybko. Próbowałem uniknąć tworzenia innego modelu. Dzięki. – jsiarto

+2

hej tadman, dla tych z nas, którzy interesują się drugą opcją, napisałem następujące pytanie: http://stackoverflow.com/questions/7841553/creating-a-feed-from-multiple-rails-models-efficiently If masz chwilę, czy mógłbyś sprawdzić kontynuację? – jay

0

Utwórz model przedmiotu, który zawiera atrybuty "nazwa_tabeli" i "identyfikator_produktu". Następnie utwórz część dla każdego typu danych. Po zapisaniu, powiedzmy, bilet, należy utworzyć instancję produktu:

i = Item.create(:table_name => 'tickets', :item_id => @ticket.id) 

W swojej items_controller:

def index 
    @items = Item.find(:all, :order => 'created_on DESC') 
end 

w widokach/przedmiotów/index.erb:

<% @items.each do |item| %> 
    <%= render :partial => item.table_name, :locals => {:item => item} %><br /> 
<% end %> 
+0

Wydaje się, że jest to bardziej ręczny sposób radzenia sobie ze STI, czy istnieje przewaga polegająca na przechowywaniu nazwy tabeli, zamiast typu i po prostu pozwalaniu szynom na obsługę STI? – jsiarto

Powiązane problemy