Search Model and will_paginate fail - ruby-on-rails

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.

Related

Rails - Combining will_paginate and ransack

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

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.

thumbs_up gem to sort liked posted - rails

I'm using the thumbs_up gem to allow users to like designs and products. In the users profile, i have it showing all of the designs and products that the user has liked. Right now, i have concatenated the designs and products into one view but they are ordered 'created_at DESC' for the designs+products. I want to order it based on when the user voted so when a user votes on a design, it's first on their profile. Here is the code i have
in the model
def favorites
Design.joins(:votes).where('voter_id = ?', self.id).where('voteable_type = ?', 'Design').where('vote = ?', true)
end
def favs
Product.joins(:votes).where('voter_id = ?', self.id).where('voteable_type = ?', 'Product').where('vote = ?', true)
end
in the controller
#user = User.find_by_username(params[:id])
#designs = #user.favorites
#products = #user.favs
#favorites = #designs.to_a.concat #products.to_a
#favorites.sort! {|t1, t2| t2.created_at <=> t1.created_at}
I've even removed the default scope for designs and products in case that was the issue but it didn't resolve it.
i've also tried this with no luck
Design.joins(:votes).where('voter_id = ?', self.id).where('voteable_type = ?', 'Design').where('vote = ?', true).order('created_at DESC')
there is a timestamp 'created_at' that belongs to each vote. so i know this is possible.
If a user has_many :votes, votes belong_to :voteable and every user only votes on a specific voteable once, I would try something like this:
#user.votes.includes(:voteable).order('created_at DESC')
This will return collection of votes ordered by their create date. Then you can iterate over them and display their voteable attribute however you want. If you only want designs and not products then you will need to do a join instead of includes and filter by voteable_type

Tire not working with will_paginate in controller

I'm currently searching two models (Posts and Channels), using Tire and ElasticSearch.
I need to add pagination using will_paginate. The issue is, Tire doesn't appear to support will_paginate in the controller (:page and :per_page don't work...). It turns out, to use pagination with Tire, you have to call it in your model.
The problem with calling Tire in my models is, if I do this, Tire won't let me search my two models (Posts and Channels) at the same time.
So... long story short... if I use Tire in the controller, I can't have pagination but I can search my two models at the same time. If I use Tire in my models, I can't search both of my models at the same time, but I can have pagination.
This just seems dumb. Is there a way around this?
For reference, here's the code from my controller that allows me to search both of my models at the same time:
def browse
#user = current_user
#search_items = Tire.search(['posts_index', 'channels_index'], load: true) do |search|
if params[:query].present?
search.query do |q|
q.string params[:query], default_operator: "AND"
end
end
search.filter :term, :visibility => ['public']
search.sort { by :created_at, "desc" }
end
#results = #search_items.results
end

Join tables when searching using Sunspot/Solr in Rails 3

I have an ActiveRecord model Products with associated Suppliers (via belongs_to/has_many association). I am using Sunspot for full-text searching. I make a search with that code:
#search = Products.search do
fulltext params[:search]
end
#products = #search.results
But I'd like to include suppliers too, so every time I call, for example,
#products.first.supplier
it wouldn't make a new request to the database. I tried to use
#search = Products.search(include: :supplier) do
but it didn't help. Is there any possible way to do that in Sunspot?
You can try this
#search = Sunspot.search[Products, Supplier] do
.....
end

Resources