Rails - Combining will_paginate and ransack - ruby-on-rails

I am using Ransack for Filtering and will_paginate for Pagination and it seems I have a problem combining both.
Analyzing memory problems of my app I saw that my Category controller was loading all entries from the database at each call.
def index
#q = Category.all_cached.paginate(:page => params[:page], :per_page => 30).ransack(params[:q])
#categories = #q.result(distinct: true)
end
In order to get the only the first entries for each page I tried the following change:
def index
#q = Category.paginate(:page => params[:page], :per_page => 30).ransack(params[:q])
#categories = #q.result(distinct: true)
end
Problem is that now the pagination is not working any longer.
Error says: Couldn't find Category with 'id'=x even though enough records are available.
I have two questions:
How can I avoid loading all entries at first call but instead per
page
As I also retrieve information about different products in
the category and I want to avoid n+1 calls, how can I add this
[includes(:product)] into the Category Controller?

Try this way:
def index
#q = Category.paginate(page: params[:page], per_page: 30).ransack(params[:q])
#categories = #q.result(distinct: true).includes(:products)
end

Related

Pagination with Rails 5 - Having two models on "newsfeed" and paginating the total?

I am building a web app that has a "newsfeed" with two models (called Event and Suggestion). Is it possible to paginate the newsfeed such that the pagination applies to the total and not either individually? Here is what I have so far in my controller. I tried simply adding the two, though that doesn't work because the result is an array, not an ActiveRecord Association. Thanks in advance!
def index
#ideas = Suggestion.paginate(:page => params[:page], per_page: 25).order('created_at DESC')
#ideas += Event.paginate(:page => params[:page], per_page: 25).order('created_at DESC')
render :index
end
Assuming you use 'will_paginate', try this. Put this in your initializers:
require 'will_paginate/array'
then you can do things like this:
#objects = (Suggestion.all + Event.all).sort_by &:created_at
#objects.paginate(:page =>params[:page], per_page: 25)
The problem here is performance. This way you will get all records from the database every time, and then perform pagination

Search Model and will_paginate fail

I'm new at the rails world, i am trying to implement will_paginate with my Search model. The Search model is responsible for searching products.
My problem is that i can't figure out how to make will_paginate works with this two models, because the products are displayed by the search model and will_paginate only deals with controllers, i have spent a couple of days trying to make this work but without luck :(
This is my Search.rb
class Search < ActiveRecord::Base
def search_products
products = Product.all
products = products.where(["modelo LIKE ?","%#{modelo}%"]).order(created_at: :desc) if modelo.present?
products = products.where(["preco >= ?",min_price]) if min_price.present?
products = products.where(["preco <= ?",max_price]) if max_price.present?
products = products.where(["troca LIKE ?","%#{troca}%"]) if troca.present?
products = products.where(["estado_id LIKE ?","%#{estado_id}%"])
return products
end
end
Search controller
def show
#search = Search.find(params[:id])
#estado = Estado.all
#products = #search.search_products.paginate(:page => params[:page], :per_page => 2).order('id DESC')
end
and search show
<%= will_paginate #products%>
I think that is missing something ;S Please guys, give me a north of how to solve this problem ;S
ps: To make the Search i followed the Railscast tutorial.

Will_Paginate Gem With Rails Displaying Results In Wrong Order

Attempting to sort an entry by an associated field, unfortunately when paginating with Will Paginate the sorting is wrong.
#categories = Category.includes(:posts)
.page(params[:page])
.order("posts.post_at DESC")
I have tried many variations, but unfortunately will paginate does not seem to respect the sort order of categories. Without the pagination the categories are sorted correctly.
How can I get Will Paginate to respect the order?
The end goal is Categories sorted by posts.post_at and paginated while maintaining that order.
Thanks.
Try
#categories = Category.includes(:posts).order("posts.post_at DESC").paginate(:page => params[:page], :per_page => 10)
Sorry can't comment due to low rep, but what are you trying to sort by and what do you want listed?
If you want categories in a certain order with the associated posts, is that by alphabetical?
#categories = Category.includes(:posts).order('categories.name??').page(params[:page])
Category with most recent posts?
#categories = Category.includes(:posts).order("posts.post_at DESC").page(params[:page])
Or are you wanting the most recent posts with the categories listed along with it?
#posts = Post.includes(:category).order('posts.post_at DESC').page(params[:page])
It's unclear what your end goal is with this query.

Group Solr results by class

I'm searching two models with Solr like so:
#query = Sunspot.search Location, Employee do
with(:category_id, params[:category_id]) if params[:category_id].present?
fulltext params[:search]
facet :category_id
order_by(:weight, :desc)
paginate :page => params[:page], :per_page => 10
end
I would like to create two discrete objects from the results, containing matches from both models so I can split them up in the UI.
I'm currently doing:
#results = #query.results.group_by(&:class)
#locations = #results[Location]
#employees = #results[Employee]
but that's not working. #locations and #employees are both empty. What am I missing here? If i debug #results, I see matches and they're already grouped by model. I just want to expose that to my view so I can split up results into hideable/showable containers. Thoughts?
I don't have solr, so I can't assume exactly what #results looks like (I assume it's a hash).
With that assumption, the hash keys are either Symbols or Strings.
So try
#locations = #results[:Location]
#employees = #results[:Employee]
or
#locations = #results["Location"]
#employees = #results["Employee"]
One of the two of those (probably the first) should give you the information in each instance variable. The reason is that ruby will set the hash keys of class names as symbols. If the names were already strings, the keys will be strings.

How can I order when using pagination?

This might be quite simple question.
Here's my code. Then I want to sort #codes ordered by the column code.user.last_active_at
#here, I retrieve only the records that contains particular keyword.
#search = Code.search do
fulltext params[:search]
with(:community_id, community_search)
paginate :page => 1, :per_page => 1000000
end
#Here, I try pagination. 10 records per each page.
#codes = #search.results
#codes = Kaminari.paginate_array(#codes).page(params[:page]).per(10)
I want to sort them ordered by the column #code.user.last_active_at
How can I do that?
I tried this
#codes = Kaminari.paginate_array(#codes.joins(:user).order('user.last_active_at DESC')).page(params[:page]).per(10)
But it returned this error
NoMethodError (undefined method `joins' for #
<Sunspot::Search::PaginatedCollection:0x0000001ca851a8>):
app/controllers/codes_controller.rb:95:in `index'
How can I sort while I'm using Kaminari pagination?
Kaminari not affect on sorting. first you have to sort and then get page(x).per(x)
so for example in your controller
#codes = #search.results
#codes = #codes.joins(:user).order('user.last_active_at DESC').page(params[:page]).per(10)
edit:
after check sunspot documentation I think you can make something like
#search = Code.search(include: :user) do
fulltext params[:search]
with(:community_id, community_search)
order_by('user.last_active_at DESC')
#paginate :page => params[:page], :per_page => 10 you can add this and not use Kaminari
end
you can try joins except include

Resources