Getting results with a column value prioritized - ruby-on-rails

Rails 3.2.8
I have the following:
def index
params[:direction] ||= "desc"
params[:sort] ||= "status"
#products = product.solr_search( include: [:customer] ){
fulltext params[:query] if params[:query].present?
with :status, (params[:status] || params[:filter]) if (params[:status] || params[:filter]).present?
order_by( params[:sort], params[:direction] ) if params[:sort].present? && params[:direction].present?
paginate page: params[:page], per_page: params[:per_page]
}.results
end
What I would like to do is do the initial sort with a priority when the status column = 'new'. In MySQL, it would be something like this:
SELECT * from product ORDER BY case when status = 'new'
Any idea what my syntax should be?

Related

will_paginate giving an error when doing a search

Alrighty, so I have searched on here repeatedly on this as well as other places but have yet to find the solution that relates to me. Probably because the previous questions were some time ago.
My problem is that I had first added pagination and then I was required to add a search so that users could search for products. When they do the search it's just supposed to open the products page. If I took out the search, the pagination doesn't give me an error.
The error I get now is
''undefined method `total_pages' for # Product::ActiveRecord_Relation:''
and the line of code highlighted for the error is the pagination in the index.html.erb.
What am I missing? Thanks for any guidance, this newbie needs it!
This is the products_controller:
def index
if Rails.env == "development"
name_env = "name LIKE ?"
else
name_env = "name ilike ?"
end
if params[:q]
search_term = params[:q]
#products = Product.search(search_term)
else
#products = Product.all
#products = Product.paginate(:page => params[:page], per_page: 4)
end
end
This is the index.html.erb :
<div class="pagination">
<%= will_paginate #products %>
</div>
You have missed paginate method when the search, it #products = Product.search(search_term) will be like this
.....
if params[:q]
search_term = params[:q]
#products = Product.search(search_term).paginate(:page => params[:page], per_page: 4)
else
#products = Product.all.paginate(:page => params[:page], per_page: 4)
.....
Additionally Remove this #products = Product.all don't need this.
After all, you just paste this instead of your code, it reduced
def index
if Rails.env == "development"
name_env = "name LIKE ?"
else
name_env = "name ilike ?"
end
if params[:q]
search_term = params[:q]
#products = Product.search(search_term)
else
#products = Product.all
end
#products = #products.paginate(:page => params[:page], per_page: 4)
end
Modify index action as follows:
def index
if Rails.env == "development"
name_env = "name LIKE ?"
else
name_env = "name ilike ?"
end
#products = params[:q] ? Product.search(params[:q]) : Product.scoped
#products.paginate(:page => params[:page], per_page: 4)
end
you should use paginate for searching too.

will_paginate for group query with sunspot 2.2.2 in rails

I am using sunspot 2.2.2 in my rails app for searching results,
I have this code for grouping in my model:
def self.search_products(params, currency = nil, page_uri = nil)
search_products = Sunspot.search(VariantPrice) do
group :code do
if params[:gallery_order].present?
order_by :price, params[:gallery_order].downcase.to_sym
elsif params[:new_arrival].present? || params[:name] == "new-arrivals"
order_by :product_created_at, :desc
else
if params[:fashion_type] == "fashion"
order_by :price, :asc
elsif params[:sort] != "lowhigh"
order_by :price, :asc
else
order_by :price, :asc
end
end
limit 1
end
end
and I have this code in my controller :
variant_prices = Product.search_products(params, #currency, request.original_fullpath)
#variant_prices = []
variant_prices.group(:code).groups.each do |group|
group.results.each do |result|
#variant_prices << result
end
end
#variant_prices = #variant_prices.paginate(:page => params[:page], :per_page => PER_PAGE_VALUE)
#variant_prices_count = variant_prices.group(:code).total
now I am getting the expected count that is #variant_prices_count, which is 1400 in my case, but I am getting #variant_prices count as 60 which is wrong in my case , here I was expecting to get 1400.and then I want to paginate with this result. cant understand whether it's will_paginate issue or something else.
Help!
You can get 1400 from the paginate instance also by Total entries
by this way replace count with total_entries
#variant_prices = #variant_prices.paginate(:page => params[:page], :per_page => PER_PAGE_VALUE)
#variant_prices.total_entries#it will return toal entries 1400

Sorting the table not working

Following the #240 Railscasts i have a list of names like this
arnold
Arnold
Victor
And when I order this by that method, i get this in asc
Arnold
Victor
arnold
And this in desc
arnold
Victor
Arnold
In my controller I have:
def index
#alunos = Aluno.search(params[:search]).order(sort_column + " " + sort_direction).paginate(:per_page => params[:npage], :page => params[:page])
end
def sort_column
Aluno.column_names.include?(params[:sort]) ? params[:sort] : "nome"
end
And this in my application_helper
module ApplicationHelper
def sortable(column, title = nil)
title ||= column.titleize
css_class = column == sort_column ? "current #{sort_direction}" : nil
direction = column == sort_column && sort_direction == "asc" ? "desc" : "asc"
link_to title, params.merge(:sort => column.downcase, :direction => direction, :page => nil), {:class => css_class}
end
end
And I'm getting this (desc, in this example):
There is something that i must include in my controller or models to order in case INsensitive?
--edited
Im using sqlite3
If you're using SQL as the underlying datastore, you could do
#alunos = Aluno.search(params[:search]).order("LOWER(#{sort_column}) #{sort_direction}").paginate(:per_page => params[:npage], :page => params[:page])

Order array. undefined method `order' for Array. Convert array into hash?

I have a City model and in city's show action I want to render hotels nearby specific locations in the city. Cities has_many locations; hotels are being searched using Geocoder near method.
To add order functionality I've followed Ryan Bates screencasts #228, but this approach doesn't seem to work with arrays, giving error undefined method `order' for #< Array:0x007f960d003430>
cities_controller.rb
helper_method :sort_column, :sort_direction
def show
session[:search_radius] = 2 if session[:search_radius].blank?
#city = City.find(params[:id])
#locations = #city.locations
#hotels = []
#locations.each do |location|
unless location.longitude.blank? || location.latitude.blank?
center_point = [location.latitude, location.longitude]
box = Geocoder::Calculations.bounding_box(center_point, session[:search_radius])
thotels = Hotel.near(center_point, session[:search_radius]).within_bounding_box(box)
else
thotels = Hotel.near(center_point, session[:search_radius])
end
#hotels += thotels if thotels
#hotels = #hotels.uniq
end
#hotels = #hotels.order(sort_column + " " + sort_direction).paginate(:page => params[:page], :per_page => 5)
#json = #locations.to_gmaps4rails
respond_with #json, :location => city_url
end
private
def sort_column
Hotel.column_names.include?(params[:sort]) ? params[:sort] : "name"
end
def sort_direction
%w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
end
My question is: should I concentrate in converting an array into hash or should I initially create hash of hotels, or maybe find completely different approach to perform sorting?
order is a method used for sorting at the database level. since #hotels is an array, you won't be able to sort using order. Try the following (not tested and you may want to include array pagination if you haven't included it yet)
#hotels = #hotels.sort_by(&:"#{sort_column}")
#hotels = #hotels.reverse if sort_direction == 'DESC'
#hotels = #hotels.paginate(:page => params[:page], :per_page => 5)

How to sort when fetching a collection of models?

I have a call on my posts_controller.rb index action:
#articles = Article.order("id desc")
I now want to be able to order by:
date
id
some_counter_attribute
My querystring will have sort=date/id/count like:
www.example.com/articles/?sort=date
How should I implement this in my controller now? Should I just use if statements?
if params[:sort] == "date"
#articles = Article.order("created_at desc")
elsif params[:sort] == "count"
#articles = ...
..
Or is there a better way?
Should this logic be in the controller or Model ideally?
Try this:
class ArticlesController
def index
#articles = Article.order(sort_order)
end
private
def sort_order
##sort_order ||= {
"date" => "created_at DESC",
"id" => "id DESC",
"comments" => "comment_count ASC"
}
##sort_order[params[:sort]]
end
end
Off course there are gems for doing this sort of things:
MetaSearch
SearchLogic
Straightforward approach could be:
#articles = Article.order("#{params[:sort]} desc")
But for "date" you have to sort by created_at. So try this:
mylist = {"date" => "created_at",
"id" => "id",
"counter" => "some_counter_attribute"}
#articles = Article.order("#{mylist[params[:sort]]} desc")

Resources