为用户搜索添加邻近过滤器

Adding proximity filter to user search

我们在我们的应用程序中设置了用户搜索,目前仅基于文本内容查询。

这就是我所拥有的:

在models/user.rb

def self.search(query)
  where("description ilike ?", "%#{query}%")
end

在app/controllers/users_controller.rb

class UsersController < ApplicationController
  before_action :authorized?
  def index
    @users = User.all
    if params[:search]
      @users = User.search(params[:search]).order("created_at DESC")
    else
      @users = User.all.order('created_at DESC')
    end
  end

在 views/index.html.erb

<%= form_tag(users_path, :method => "get", id: "search-form") do %>
  <%= text_field_tag :search, params[:search], placeholder: "Search Users" %>
  <%= submit_tag "Search", :name => nil %>
<% end %>

我们正在使用 rails 和 postgres。 Geocoder gem 已安装。我们将当前的纬度和经度存储在单独的列中。

我将如何添加邻近搜索过滤器,我将在 MVC 方面采取哪些步骤?

位置正在像这样存储在我们的方案中

 create_table "users", force: :cascade do |t|
    t.float    "latitude"
    t.float    "longitude"

是的,地理编码器主页没有太多信息。我在实际的自述文件中找到了更多细节:

https://github.com/alexreisner/geocoder#readme

如果您想按邮政编码搜索,您需要在表单中添加一个文本字段输入 - 让我们称之为 zip_code。如果您想要可变距离,还要添加一个 select 标签,其中包含以英里为单位的数值,将此字段命名为 distance.

然后服务器端需要将zip转换为经纬度。

zip_result = Geocoder.search(params[:zip_code])
# Is an array of results, take the first one
if zip_result 
  result = zip_result.first
  lat = result.latitude
  lon = result.longitude

  # now we can search with our model: we are asking
  # Show me all Users within "distance_in_miles" of this geocoded
  # zip code
  distance_in_miles = params[:distance].to_i
  User.search(params[:query]).near([lat, lon], distance_in_miles)
end

这没有任何错误检查或验证 - 它基本上是一个概念证明。

知道了。我将用户控制器上的索引函数修改为

if params[:search]
  @users = User.search(params[:search]) \
    .near([current_user.latitude, current_user.longitude], 10) \
    .order("created_at DESC")
end