how to use will_paginate with ransack in rails
Asked Answered
R

1

5

I am using ransack for search and now I want to implement pagination in my rails app. So I am using the will_paginate gem. The issue am facing is that I cant figure out how to put the paginate in my current controller code as its already fetching results based on the query.

Here is my controller code

def search
if params[:search].present? && params[:search].strip != ""
  session[:loc_search] = params[:search]
end
arrResult = Array.new
if session[:loc_search] && session[:loc_search] != ""
  @rooms_address = Room.where(active: true).near(session[:loc_search], 5, order: 'distance')
else
  @rooms_address = Room.where(active: true).all
end

@search = @rooms_address.ransack(params[:q])
@rooms = @search.result

@arrRooms = @rooms.to_a

Could someone tell me how to put pagination here?

update with logs

18:29:40 web.1    |   Room Load (0.8ms)  SELECT  rooms.*, 3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((12.9715987 - rooms.latitude) * PI() / 180 / 2), 2) + COS(12.9715987 * PI() / 180) * COS(rooms.latitude * PI() / 180) * POWER(SIN((77.5945627 - rooms.longitude) * PI() / 180 / 2), 2))) AS distance, MOD(CAST((ATAN2( ((rooms.longitude - 77.5945627) / 57.2957795), ((rooms.latitude - 12.9715987) / 57.2957795)) * 57.2957795) + 360 AS decimal), 360) AS bearing FROM "rooms" WHERE "rooms"."active" = $1 AND (rooms.latitude BETWEEN 12.754501025333727 AND 13.188696374666272 AND rooms.longitude BETWEEN 77.37177993269385 AND 77.81734546730614 AND (3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((12.9715987 - rooms.latitude) * PI() / 180 / 2), 2) + COS(12.9715987 * PI() / 180) * COS(rooms.latitude * PI() / 180) * POWER(SIN((77.5945627 - rooms.longitude) * PI() / 180 / 2), 2)))) BETWEEN 0.0 AND 15)  ORDER BY distance LIMIT 5 OFFSET 5  [["active", "t"]]
18:29:40 web.1    |    (0.3ms)  SELECT COUNT(*) FROM "rooms" WHERE "rooms"."active" = $1 AND (rooms.latitude BETWEEN 12.754501025333727 AND 13.188696374666272 AND rooms.longitude BETWEEN 77.37177993269385 AND 77.81734546730614 AND (3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((12.9715987 - rooms.latitude) * PI() / 180 / 2), 2) + COS(12.9715987 * PI() / 180) * COS(rooms.latitude * PI() / 180) * POWER(SIN((77.5945627 - rooms.longitude) * PI() / 180 / 2), 2)))) BETWEEN 0.0 AND 15)  [["active", "t"]]
Rosenthal answered 21/12, 2015 at 12:11 Comment(0)
E
11

You paginate the results of your search, so after ransack. Something like @rooms = @search.result.paginate(page: params[:page], per_page: params[:per_page]) should work.

Evangel answered 21/12, 2015 at 12:20 Comment(7)
Thanks it works..But isnt it better to first do the pagination or... in this scenario is this the best approach?Rosenthal
Not really - ransack can also do sorting, not just searching, and you usually don't want just the current page of results sorted.Evangel
so is it an overkill to use willpaginate while using ransack?Rosenthal
Both have their uses, and they really are different things - ransack is for search/sorting, will_paginate for splitting the results in batches.Evangel
yes..the issue with my current implementation is that if i try next page it is still doing another database query where the results are fetched based on that particular query and then output lets say 5 of them by will_paginate..So if there are 100 listings which satisfy that ransack params then the pagination will take only 5 of them..which makes fetching the other 95 records unnecessary..Is there a way in ransack to limit search like first 5, then next 5 and so??Rosenthal
That's what pagination does - if you're looking at the SQL it generates, it does it with LIMIT and OFFSET so even if you have 100 matching records, only one page of results (in your case 5 records) is actually fetched from the DB.Evangel
I got the point now..But in my log which i updated you can see that there is limit and offset...but the one below that doesnt have those..I can also see that it took less time than the first one..Why is there a second database call?Rosenthal

© 2022 - 2024 — McMap. All rights reserved.