I memcached (with Dalli client) some of my search results like..
def self.city_search city, per_page, page, order
Rails.cache.fetch("#{city}_#{page}_#{order}") do
Post.search(:include => [:poster, :category],:geo =>
location_lat_lng_radian(city),
:with => {"@geodist" => 0.0..(Constants::PROXIMITY *
Constants::METERS_PER_MILE), :status => Post::STATUS['approved']},
:latitude_attr => :lat, :longitude_attr
=> :lng, :per_page => per_page, :page => page, :order =>
(ModelHelpers.determine_order_search order))
end
end
##In controller
@search_results = Search.city_search params[:city], params[:per_page]
|| Constants::LISTINGS_PER_PAGE, params[:page] || 1, params[:order] ||
'distance'
The result is presented in the view with pagination like..
<%= page_entries_info @search_results, :entry_name => "Search Result"
%>
<%= will_paginate @search_results, :class => 'pagination' %>
The first hit i.e. when the block is exececuted and the return type of the collection is "ThinkingSphinx::Search" this all works fine. The 2nd time when there is a cache hit and the collection returned from the city_search method is of type "Array" I get the following error.
If I convert the results of the block to an array so that the view always get an Array (regardless of cached or non cached hit), the first hit i.e. non-cached hit, get the same exact error.
Will paginate's page_entires_info expect a collection..so why am I seeing this? Not sure if this is a will paginate or thinkingsphinx issue.
undefined method `total_pages' for #<Array:0xa068c40>
/usr/local/lib/ruby/gems/1.8/gems/will_paginate-2.3.14/lib/
will_paginate/view_helpers.rb:171:in `page_entries_info'
/home/username/Apps/myapp/app/views/searches/_search_results.html.erb:
7:in
`_run_erb_app47views47searches47_search_results46html46erb_locals_object_paginate_search_results'
/home/username/Apps/myapp/app/views/searches/index.html.erb:4:in
`_run_erb_app47views47searches47index46html46erb'
/home/username/Apps/myapp/app/controllers/searches_controller.rb:28:in
`index'
Update
OK, the issue is related to the face that the collection needs to be of type Will_Paginte::Collection. TS Search by default returns the results of this type, that why it works when the block is executed, but memcached returns just an array and hence it doesn't work.
I tried converting the memcached Array to a will_paginate:collection type like...
if results.class == ThinkingSphinx::Search
return results
else
pag_results = WillPaginate::Collection.create(page, per_page) do |pager|
pager.replace(results)
unless pager.total_entries
# the pager didn't manage to guess the total count, do it manually
pager.total_entries = results.count ##this is bad
end
end
return pag_results
end
But the problem is results does not contain the entire search count, only the first paginated lot and without doing the search all again, I can't calculate the exact count, which would defeat the purpose of memcaching it, since everytime there is a cache hit I would have to run the search again just to find the total count.
Bump!