2010-02-11 3 views
8

Je travaille sur une application qui a quelques modèles différents (tickets, messages, rapports, etc.). Les données sont différentes dans chaque modèle et je veux créer un "flux" à partir de tous ces modèles qui affiche les 10 entrées les plus récentes dans l'ensemble (un mélange de toutes les données).Création de "flux" à partir de plusieurs modèles de Rails différents

Quelle est la meilleure façon de procéder? Dois-je créer un nouveau modèle de flux et écrire dans cette table lorsqu'un utilisateur reçoit un ticket ou qu'un nouveau rapport est publié? Nous avons également étudié STI pour construire une table de références de modèles ou simplement créer une méthode de classe qui agrège les données. Vous ne savez pas quelle méthode est la plus efficace ...

Répondre

6

Vous peut le faire de deux façons en fonction des exigences d'efficacité.

La méthode moins efficace est de récupérer 10 * N éléments et trier et réduire au besoin:

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

Une autre méthode consiste à créer une table d'index qui a une association polymorphique avec les différents dossiers. Si vous ne souhaitez afficher que 10 à la fois, vous pouvez l'élaguer de manière agressive en utilisant une sorte de tâche de rake pour la limiter à 10 par utilisateur, ou quelle que soit la portée requise.

+0

Cela fonctionne bien et semble se déplacer assez rapidement. J'essayais d'éviter de créer un autre modèle. Merci. – jsiarto

+2

hey tadman, pour ceux d'entre nous intéressés par la deuxième option, j'ai écrit une question de suivi ici: http://stackoverflow.com/questions/7841553/creating-a-feed-from-multiple-rails-models-efficiently Si vous avez un moment, pourriez-vous vérifier le suivi? – jay

0

Créez un modèle d'élément qui inclut les attributs "nom_table" et "élément_id". Créez ensuite un partiel pour chaque type de données. Après avoir enregistré, disons, un billet, créez une instance d'objet:

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

Dans votre items_controller:

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

Dans les vues/articles/index.erb:

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

Cela semble être une façon plus manuelle de faire simplement du STI, y a-t-il un avantage à stocker le nom_table au lieu du type et juste laisser les rails gérer le STI? – jsiarto

Questions connexes