我目前正在做一项工作,这项工作只能通过修改API的旧代码来解决。我以前从未使用过Ruby/Rails,所以我面临着一些挑战,无法正确理解如何做到这一点,但我相信它非常简单。
在控制器文件中,我能够创建一个新的端点,通过HTTP请求返回数据库中可用的所有信息。用户发出的请求发送两个参数:纬度和经度,得到的结果将是一个按每个地方与这些坐标的距离排序的地方列表。我使用的代码如下:
def myfunction
@host = "#{request.protocol}#{request.host_with_port}"
# Filters
@projects = Project.published
# Coordinates and distance
lat = geocode_params.fetch('latitude')
lon = geocode_params.fetch('longitude')
origin = Geokit::LatLng.new(lat, lon)
distance_sql = Project.distance_sql(origin)
# Getting closest places
if (params[:latitude] != nil)
ceil = params[:latitude].to_i + 1
floor = params[:latitude].to_i - 1
@projects = @projects.where('official_lat > ? AND official_lat < ?',floor,ceil)
end
if (params[:longitude] != nil)
ceil = params[:longitude].to_i + 1
floor = params[:longitude].to_i - 1
@projects = @projects.where('official_long > ? AND official_long < ?',floor,ceil)
end
@projects = @projects.page(params[:page]).per(@items_perpage).order("#{distance_sql} ASC").limit(15)
render json: @projects, meta: {count: @projects.total_count}, host: @host
end
我把这个";distance_sql";来自另一段代码,但据我所知,它为项目中的每个项目生成了一个新的变量,其中包含位置和通过HTTP请求传递的坐标之间的距离(以公里为单位(。
我只是想把这个距离包括在API返回的参数中。由于它被创建为";在旅途中";,我找不到将其包含在序列化程序文件中的方法。
我还试图将其添加到代码的末尾,但端点停止工作:
@projects = Project.includes(:distance_sql)
render :json => @projects.to_json(:include => :distance_sql), meta: {count: @projects.total_count}, host: @host
有可能这样做吗?提前感谢
编辑:我想"sql_distance"返回了以公里为单位的距离,因为这个API用于返回50公里内的所有位置,在控制器代码中我发现:
@projects_latlong = Project.published.within(50, origin: [lat, lon]).order("#{distance_sql} ASC").limit(MAX_PROJECTS_TO_SHOW)
我以为这是获得50公里半径内地点的命令,但我不能100%确定;在";命令,但没有成功。
如果可能的话,我会使用地理编码器gem,它可以直接进行地理空间查询:
class Project < ApplicationRecord
geocoded_by :address
end
这可以让你把整个混乱归结为:
@projects = Project.published.then do |scope|
lat, lon = params[:latitude], params[:longitude]
if lat.present? && lon.present?
scope.near(lat, lon).order(distance: :asc)
else
scope
end
end.page(params[:page])
.per(@items_perpage)
.limit(15)