1
votes

I have some code like:

if @sort_by == 'distance'
  Opportunity.upcoming_unsorted \
             .is_geocoded \
             .near([@query_location.latitude, @query_location.longitude], MilesRadius) \
             .paginate(:page => @page, :per_page => PerPage)
else # Opp. date
  Opportunity.upcoming_unsorted \
             .is_geocoded \
             .near([@query_location.latitude, @query_location.longitude], MilesRadius, :order => false) \
             .order('opportunity_date') \
             .paginate(:page => @page, :per_page => PerPage)
end

I was wondering if it's possible to do this in one rails model search instead of putting the conditional on the if @sort_by.

Basically, I'm giving the user the option to sort by geographic distance (powered by geocoder gem), or 'opportunity_date' field on the model. And want to know if this code can be simplified somehow using rails 5.0. Note: geocoder provides a model .distance field in rails ORM but it's not in the database itself.

2

2 Answers

0
votes

You can do this by conditionally adding the order condition and setting order on .near programmatically. Something like:

query = Opportunity.upcoming_unsorted
  .is_geocoded
  .near([@query_location.latitude, @query_location.longitude], MilesRadius, order: @sort_by == 'distance')
query = query.order('opportunity_date') if @sort_by != 'distance'
query.paginate(page: @page, per_page: PerPage)
0
votes

Adam's answer may work for you, but for me, I actually had an even more complicated query (using an OR condition) that I needed to add as well.

Normally, one would use arel_table to accomplish something like we are trying to do here. In this scenario, we can't because geocoder's "near" method is not arel-compatible (please let me know if this is not the case and I will update the answer).

As such, what I had to end up doing was still use two queries plus a conditional. I ended up collecting the IDs of the records, then in a separate query, doing the sorting/pagination. (I was trying to optimize for code cleanliness and not necessarily query efficiency.)