views:

166

answers:

4

I apologize if this is a trivial question or my understanding of rails is weak.

I have 2 actions in my controller, index and refine_data.

index fetches and displays all the data from a database table.

refine_data weeds out unwanted data using regex and returns a subset of the data.

Controller looks like:

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

I would like to redirect the refine_data action to the same view (index) with new_results.

As new_results are not from the database table (or model), how do I go about constructing my paginate?

A: 

As I wrote in my answer to Sort by ranking algorithm using will-paginate, it is possible to use a custom find method to order the data.

It could be used similar to filter out unwanted data, since you just need to return a set of data. By modifying the name of your refine_data to something like find_refined_data you can use

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

in your index method. (Of course you need to return a set of records instead redirect to the index action)

BTW you could also use the paginate_by_sql method, if you are able specify your filter as a SQL query. This is probably more efficient than grabbing all records and performing a regex on them. But more complex I guess.

Veger
Veger, thanks for the suggestions.I placed the find_refined_data (search_string, page) in my model.I added the following line to my controller action refine_data Result.paginate_refined_data params[:exclude], params[:page]However, I am seeing the error 'parameter hash expected'I am guessing that paginate_refined_data needs additional parameters. I am not sure which.I also need to pass in the search string to my model from the controller apart from the will_paginate params.Thanks a lot for your help
truthSeekr
The `find` method (and thus yours as well) requires one argument (see http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M002263). It is a hash-list from which you can subtract the options using `extract_options!` or something similar, so you can use them for your own code.
Veger
A: 

I was not successful in getting will_paginate to work by creating my own find method. I was almost successful but not quite.

Here's what I've tried: In Controller:

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

In Model:

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

will_paginate had trouble with me passing an additional parameter :exclude which it did not understand.

The simplest solution for me was to create my own WillPaginate::Collection object.

So here's how mine works now:

#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

Hope this will help any of the guys facing the same problem:

truthSeekr
A: 

I'm not sure about the other answers - you may well want to move that method into your model class.

But answering your actual question. The way to show the same view as another action is not to redirect but use:

render :action => :index
Taryn East
A: 

Yet another alternative might be to create a named_scope for your refined result set. Can you formulate your "get_subset" business logic into database-style commands?

If so you can reconstruct your finder as a named_scope (with those conditions) eg:

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

and then just call paginate on that:

Result.blue_things.paginate :per_page => 5, :page => params[:page]
Taryn East