Sorting a result defined by remote parameters - ruby-on-rails

i have this index action:
def index
limit = params[:limit]
page = params[:page]
sort = params[:sort].split(',')
#term = nil
if params[:search]
#term = params[:search]
#lessons = policy_scope(Lesson).search(#term)
.order("#{sort[0]} #{sort[1].upcase}")
.paginate(page: page, per_page: limit)
else
#lessons = policy_scope(Lesson).order("#{sort[0]} #{sort[1].upcase}")
.paginate(page: page, per_page: limit)
end
end
which is fed by a vuejs frontend with a vuetify datatable and its purpose is to send out an array of lesson objects, filtered and sorted by the frontend.
this works pretty good with default rails..
however, with the mobility gem involved there is no fieldname "title" for example or "title_en", so the order stops working. in mobility you have some "fake column names" and it automagically handles it to search for the value in a key-value table ( https://github.com/shioyama/mobility#getting-started )
so i sat me down and fired up the console and figured out that:
.order(title: :desc) - works
.order(title_en: :asc) - works
everything with strings involved, like .order('title DESC') or .order('title_en ASC') does not work and results in an error like
ActionView::Template::Error (PG::UndefinedColumn: ERROR: column
"title_en" does not exist LINE 1: SELECT "lessons".* FROM "lessons"
ORDER BY title_en ASC LIMI...
is there a way i could get this working? maybe there is something to generate title: out of 'title'? Or some other magic?
thanks!

You can call the order method like this instead:
.order(sort[0] => sort[1])
Passing "a" => "b" to a method is the same as passing "a": "b".

Related

Rails: SQLite3::SQLException: near "from": syntax error

I have an issue with a sort by year filter on my rails app; when i attempt to select a year from my view, the app crashes with this error: SQLite3::SQLException: near "from": syntax error
The code(passed down from the previous dev who has moved on) for the filter in my control is this:
#posts = Post.where('extract(year from sort_date) = ?', params[:year])
.paginate(page: params[:page], per_page: 5)
.order('sort_date DESC')
render 'index'
end
i might be wrong but i am assuming it's the 'extract(year from sort_date) = ?' in the code? but i am unsure, also for reference the reference parameter is: {"year"=>"2017"}
I attempted to make it look more like a postgres query("EXTRACT(year FROM sort_date) = ?" but still it fails, with the exact same SQL error(Rails: SQLite3::SQLException: near "from")
SQLITE3 does not support the extract() function. You have to use strftime().
#posts = Post.where("strftime('%Y', sort_date) = ?", params[:year])
.paginate(page: params[:page], per_page: 5)
.order('sort_date DESC')
render 'index'
end

Filtering in Spree 3.1

I need product properties' filters on taxon's show page.
Heres's what i've added to my spree/taxon_controller.rb show method:
if params[:filter].present?
params[:filter].each do |k,v|
pp=#product_properties.where("property_id = ? and value in (?)", #properties.find_by(name: k), v).pluck(:id)
#products = #products.joins(:product_properties).where("spree_product_properties.id in (?)", pp)
end
end
I trying to do similiar query in console:
Spree::Product.joins(:product_properties).where("spree_product_properties.id in ?", [3,23]).where("spree_product_properties.id = ?", 4)
But it returned nothing.
If delete last where-statement, it's all ok
Spree::Product.joins(:product_properties).where("spree_product_properties.id in ?", [3,23])
One product object contain product_properties with id 3 and 4.
What i do wrong?
P.S. First i try to use spree's filter system with custom search as it write here, but it didn't work at all.
P.P.S I think filters is preetty stndart feature for e-shop, why it so many problems with them in spree?!

Sorting 2 colums in a table in Ruby on Rails using haml

I am kind of new at rails, currently using version 3.23 and I am trying to enable 'sort' on two columns in my table. I managed to create the links on these column headers and actually got one column working/sorting!But couldnt achieve the same result when I modified my code in the movie controller rb, my code can only work for one column! is:
def index
#movies = Movie.all.sort_by { |movie| movie.title }
end
Works perfectly, but when I combine another parameter i.e. release date I get an error!
def index
#movies = Movie.all.sort_by { |movie| movie.title } then { |release date| release.date}
end
Can someone please help me resolve this issue? I have researched it on google but I've gotten nothing conclusive!. Any help will be most appreciated.
Assuming that you have to sort on title and release_date fields in movies table.
You can perform the sorting at database level itself as below:
In Rails 4.x:
Below will sort all the movie records with title and release_date in ascending order(as default).
def index
#movies = Movie.order(:title, :release_date)
end
If you want to change the order, you can specify as asc or desc as:
def index
#movies = Movie.order(title: :asc, release_date: :desc)
end
In Rails 3.x:
def index
#movies = Movie.all(:order => "title ASC, release_date ASC")
end
If you want to change the order, you can specify as DESC in the above case.
You can order your listing by this
def index
#movies = Movie.order(title: :asc, release_data: :desc)
end

Where Clause - Ruby on Rails

I am new to Ruby on Rails and am having trouble with a simple where with a model.
When I try to do Test #1 the results are out of order. New items get pushed to the bottom no matter what.
def index
#user = User.where(:status => false).order(last_name: :desc).all
end
If I enter this into rails console it doesn't work also but if I remove the all it works perfectly in rails console but doesn't work in the UsersController.
What is the proper way to do a where clause with an order? Thanks for your help!
UPDATE:
I have updated the code to the following but the results are still out of order:
def index
#user = User.where(status: false).order('last_name DESC')
end
You should use order('last_name DESC') instead of order(last_name: :desc).
order(last_name: :desc) will produce sql like (That's why your order doesn't work):
ORDER BY '---\\n:last_name: :desc\\n'
order('last_name DESC') will produce sql right:
ORDER BY last_name DESC
Rails 4
def index
#user = User.where(status: false).order('last_name DESC')
end

rails tire elasticsearch weird error

I have indexed a Car model with one car record mercedes benz in the database. If I search for the word benz I get an error:
ActiveRecord::RecordNotFound in CarsController#index
Couldn't find all Cars with IDs (1, 3) (found 1 results, but was looking for 2)
If I search for hello I get:
Couldn't find Car with id=2
Other random search terms work returning accurate results.
So it's basically random errors generated by random search terms. What could be the cause of this?
Controller:
def index
if params[:query].present?
#cars = Car.search(params)
else
#cars = Car.paginate(:page => params[:page], :per_page => 10)
end
end
Model:
def self.search(params)
tire.search(load: true, page: params[:page], per_page: 10) do |s|
s.query { string params[:query]} if params[:query].present?
end
end
This happens because, you are using the load => true option to load the search results from database. The activerecord seems to be missing in DB, but the elasticsearch index contains the same document.
Reindex is not always the solution IMHO.
The best solution is to delete the document when it is deleted in db. You can use the after_destroy callback for this.
Tire remove api is used to remove a single document from index.
Tire.index('my-index-name').remove('my-document-type', 'my-document-id')
Reference: https://github.com/karmi/tire/issues/43

Resources