2010-02-17 5 views
1

Je m'excuse si c'est une question triviale ou si ma compréhension des rails est faible.will_paginate sans utilisation de activerecord

J'ai 2 actions dans mon contrôleur, index et refine_data.

index récupère et affiche toutes les données d'une table de base de données. Refine_data supprime les données indésirables en utilisant regex et retourne un sous-ensemble des données.

Controller ressemble:

def index 
    Result.paginate :per_page => 5, :page => params[:page], :order => 'created_at DESC' 
end 

def refine_data 
    results = Result.all 
    new_results = get_subset(results) 
    redirect_to :action => 'index' 
end 

Je voudrais rediriger l'action refine_data à la même vue (index) avec new_results. Comme les nouveaux résultats ne proviennent pas de la table (ou du modèle) de la base de données, comment puis-je construire mon paginate?

Répondre

2

Je n'ai pas réussi à faire fonctionner will_paginate en créant ma propre méthode de recherche. J'étais presque réussi mais pas tout à fait.

Voici ce que j'ai essayé: Contrôleur:

def refine_data 
Result.paginate_refined_data :per_page => 5, :page => params[:page], :order => 'created_at DESC', :exclude =>"somestring" 
end 

Model:

def find_refined_data(args) 
    exclude_string = args[:exclude]; 
    new_results = do_some_work_and_exclude_records(@results,exclude_string) 
end 

will_paginate a eu du mal avec moi passer un paramètre supplémentaire: exclure laquelle il ne comprenait pas.

La solution la plus simple pour moi était de créer mon propre objet WillPaginate :: Collection.

est donc ici comment fonctionne moi maintenant:

#The method name does not cause will_paginate to intercept and try to do its magic. 
def new_find_refined_data(args) 
    exclude_string = args[:exclude]; 
    new_results = do_some_work_and_exclude_records(@results,exclude_string) 
    @entries = WillPaginate::Collection.create(1, args[:per_page]) do |pager| 
    # inject the result array into the paginated collection: 
    pager.replace(new_results) 

    unless pager.total_entries 
    # the pager didn't manage to guess the total count, do it manually 
    pager.total_entries = new_results.length 
    end 
end 

end 

Espérons que cela aidera à l'un des gars face au même problème:

2

Comme je l'ai écrit dans ma réponse à Sort by ranking algorithm using will-paginate, il est possible d'utiliser une méthode de recherche personnalisée pour ordonner les données.

Il pourrait être utilisé de manière similaire pour filtrer les données indésirables, puisque vous avez juste besoin de retourner un ensemble de données. En modifiant le nom de votre refine_data à quelque chose comme find_refined_data vous pouvez utiliser

Result.paginate_refined_data :per_page => 5, :page => params[:page], :order => 'created_at DESC' 

dans votre méthode index. (Bien sûr, vous devez retourner un ensemble d'enregistrements au lieu de réacheminer à l'action de l'indice)

BTW vous pouvez également utiliser la méthode paginate_by_sql, si vous êtes en mesure d'indiquer votre filtre comme une requête SQL. C'est probablement plus efficace que de saisir tous les enregistrements et d'effectuer une regex sur eux. Mais plus complexe je suppose.

+0

Veger, merci pour les suggestions. J'ai placé le find_refined_data (search_string, page) dans mon modèle. j'ai ajouté la ligne suivante à mon action contrôleur refine_data Result.paginate_refined_data params [: exclude], params [: page] Cependant, je vois le « hachage de paramètre attendu » d'erreur Je suppose que paginate_refined_data a besoin des paramètres supplémentaires. Je ne suis pas sûr de qui. J'ai également besoin de transmettre la chaîne de recherche à mon modèle depuis le contrôleur en plus des paramètres will_paginate. Merci beaucoup pour votre aide – truthSeekr

+0

La méthode 'find' (et donc la vôtre aussi) nécessite un argument (voir http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M002263). C'est une liste de hachage à partir de laquelle vous pouvez soustraire les options en utilisant 'extract_options!' Ou quelque chose de similaire, de sorte que vous pouvez les utiliser pour votre propre code. – Veger

0

Je ne sais pas sur les autres réponses - vous pouvez bien vouloir déplacez cette méthode dans votre classe de modèle.

Mais répondant à votre question actuelle. La façon de montrer la même vue que une autre action est de ne pas rediriger, mais l'utilisation:

render :action => :index 
0

Une autre solution pourrait être de créer un named_scope pour votre jeu de résultats raffiné. Pouvez-vous formuler votre logique métier "get_subset" dans des commandes de style base de données?

Si oui, vous pouvez reconstruire finder comme named_scope (ces conditions) par exemple:

named_scope :blue_things, :conditions => {:colour => 'blue'} 

puis il suffit d'appeler paginate sur ce point:

Result.blue_things.paginate :per_page => 5, :page => params[:page] 
Questions connexes