[RUBY] Get location information in Rails and sort in ascending order

Thing you want to do

Gets objects within the specified range from a certain point and sorts the objects in order of closeness.

Try

Make geokit-rails available

Use geokit-rails as a location-related gem. I think there are various other gems, but I will use this for personal reasons. The setup is written on github, so it is omitted. https://github.com/geokit/geokit-rails

The model after setup looks like this.

user.rb


class User < ApplicationRecord
    acts_as_mappable default_units: :kms, default_formula: :sphere
end

Specify the range and get the object

First, get an object that exists within a radius of n kilometers from a certain point. Here, Tokyo Tower is represented by latitude and longitude, and 5km is specified from there.

users_controller.rb


def index
    users = User.within(5, origin: [35.658694, 139.745390])
end

This will calculate the distance from the lat, lng columns (by default) and retrieve the object.

Sort the retrieved objects in order of closeness

In the README

You can add order clauses in the chain as for any ActiveRecord query Location.within(5, :origin => @somewhere).order('nbr_seats ASC') You can even sort by distance (use the same name as specified in the model class) Location.within(5, :origin => @somewhere).order('distance DESC, nbr_seats ASC')

Because it is written, when I try it

$ rails c --sandbox
> users = User.within(5, origin: [35.658694, 139.745390]).order('distance DESC, nbr_seats ASC')

I got the following error.

ActiveRecord::StatementInvalid (Mysql2::Error: Unknown column 'distance' in 'order clause')

Looking at the issue, it seems that the distance field has been removed. https://github.com/geokit/geokit-rails/issues/39 https://github.com/geokit/geokit-rails/issues/56 However, since it is old information, I'm sorry if it is different now.

In the README

The plug-in creates a calculated distance field on AR instances that have been retrieved through a Geokit location query. By default, these fields are known as "distance" but this can be changed through the :distance_field_name key.

I would be grateful if you could tell me if it is different.

However, I couldn't do it in my environment, so I will proceed by saying that I can't.

First, it is necessary to hold the distance from the specified location (Tokyo Tower in this case) as a state for each of the extracted objects, but since I thought that it was not necessary to hold it in the column, I modeled the virtual (?) Attribute. I will give it to you. Here, it is distance.

user.rb


attr_accessor :distance
#abridgement

Next, we need to find the distance to put in: distance. This can be achieved with the geokit-rails distance_from method.

$ rails c --sandbox
> user = User.first
> user.distance_from([35.658694, 139.745390])
>The distance to that user is the return value.

In order to actually put this obtained distance temporarily in: distance, define an instance method.

user.rb


def get_distance(lat, lng)
    self.distance = distance_from([lat, lng])
end
#abridgement

Each object can now keep a distance from the specified point. Add each syntax to the controller.

users_controller.rb


def index
    users = User.within(5, origin: [35.658694, 139.745390])
    get_distance_users = users.each {|user| user.get_distance(35.658694, 139.745390)}
end

However, this has not been sorted yet. This is done using ruby's sort_by method.

users_controller.rb


def index
    users = User.within(5, origin: [35.658694, 139.745390])
    get_distance_users = users.each {|user| user.get_distance(35.658694, 139.745390)}
    sorted_users = get_distance_users.sort_by {|a| a.distance}
end

You now have an array of objects sorted in ascending order based on: distance in sorted_users.

Recommended Posts

Get location information in Rails and sort in ascending order
I tried to sort the data in descending order, ascending order / Rails
[Rails] Ranking and pagination in order of likes
Get location information quickly
Get Android location information
How to sort in ascending / descending order with SQLite
Get UserAgent in [Rails] controller
Get information in an instance and calculate numbers Standard version
Get error information using DefaultErrorAttributes and ErrorAttributeOptions in Spring Boot 2.3
Sorting in ascending order in Java (bubble sort: simple exchange algorithm)
Sort List in descending order in Java and generate a new List non-destructively
Enable jQuery and Bootstrap in Rails 6 (Rails 6)
[Java] Get the dates of the past Monday and Sunday in order
Remove "assets" and "turbolinks" in "Rails6".
[Rails] How to get the user information currently logged in with devise
[Rails] Use devise to get information about the currently logged in user
Make bubble sort and selection sort in Ruby
Get weather forecast from OpenWeatherMap in Rails
Get YouTube video information with Retrofit and keep it in the Android app.
Get contextual information such as HttpServletRequest in Jersey
[Order method] Set the order of data in Rails
(Basic authentication) environment variables in rails and Docker
Rails logger Get a rough idea in 1 minute
Library "OSHI" to get system information in Java
[Rails] How to get success and error messages
[Rails] ActiveRecord :: HasManyThrough Order Error in Users # show