Ordering ActiveRecord Relationship over column temporary field in Rails
I need to order a query of Profile
records in an object ActiveRecord::Relation
by value that is calculated at runtime.
I created and assigned a temporary column distance
in my controller for an object Relation
using attr_accessor
this way:
@profiles.each do |p|
p.class_eval do
attr_accessor :distance
end
end
@profiles.each do |p|
p.distance = distance_arr[@profiles.index(p)] # Distance values obtained from an instance array
end
However, when I try to order Relation
using the order method, I get an error no such column: distance
i.e. not raising the temporary field.
This is how I tried to order it in my controller (note that I am using a gem will_paginate
, but it doesn't matter).
@profiles = @profiles.order('distance ASC').paginate(page: params[:page])
source to share
You have added a distance attribute to profile instances. So the distance stuff is in ruby ββand sql doesn't know anything about it. Since you are calculating distances in ruby, you need to order them in ruby. You can use the sort_by method.
@profiles.sort_by{|p| p.distance}
Alternatively, you can push calculating distance in sql. Something like the following
@profiles = Profile.select('*, 10 as distance').order('distance')
Here you can see that the computed distance column has been added to the selection, which tells the active record that the query has changed.
source to share