2010-02-11 3 views
8

Sto lavorando a un'applicazione con alcuni modelli diversi (ticket, post, report, ecc.). I dati sono diversi per ogni modello e voglio creare un "feed" da tutti quei modelli che visualizzano le 10 voci più recenti su tutta la linea (un mix di tutti i dati).Creazione di "feed" da più modelli di Rails diversi

Qual è il modo migliore per farlo? Devo creare un nuovo modello di feed e scrivere su quella tabella quando viene assegnato un ticket a un utente o viene pubblicato un nuovo report? Abbiamo anche esaminato STI per creare una tabella di riferimenti modello o semplicemente creando un metodo di classe che aggrega i dati. Non sei sicuro di quale sia il metodo più efficace ...

risposta

6

È può farlo in due modi, a seconda dei requisiti di efficienza.

Il metodo meno efficace è quello di recuperare i 10 * N elementi e ordinare e ridurre come richiesto:

# 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] 

Un altro metodo è quello di creare una tabella di indice che ha ottenuto un'associazione polimorfica con i vari record. Se sei interessato solo a mostrare 10 alla volta, puoi sfoltire in modo aggressivo usando un qualche tipo di rake task per limitarlo a 10 per utente, o qualunque scope sia richiesto.

+0

Funziona bene e sembra muoversi abbastanza velocemente. Stavo cercando di evitare di creare un altro modello. Grazie. – jsiarto

+2

hey tadman, per quelli di noi interessati alla seconda opzione, ho scritto una domanda di follow-up qui: http://stackoverflow.com/questions/7841553/creating-a-feed-from-multiple-rails-models-efficiently If hai un momento, potresti controllare il seguito? – jay

0

Creare un modello di articolo che includa gli attributi "nome_tabella" e "elemento_elemento". Quindi creare un partial per ogni tipo di dati. Dopo aver salvato, diciamo, un biglietto, creare un'istanza dell'oggetto:

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

Nel vostro items_controller:

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

In vista/oggetti/index.erb:

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

Questo sembra essere un modo più manuale di fare solo STI, c'è un vantaggio nell'archiviazione di nome_tabella, invece di tipo e solo lasciando che le rota gestiscano lo STI? – jsiarto