Ruby on rails Rails/ActiveRecord—如何将订单的计算结果存储在模型上,以便稍后在请求中使用

Ruby on rails Rails/ActiveRecord—如何将订单的计算结果存储在模型上,以便稍后在请求中使用,ruby-on-rails,rails-activerecord,dds-format,Ruby On Rails,Rails Activerecord,Dds Format,因此,我有一个空间查询,根据给定的lat/lng获取用户的位置。查询如下所示: Location. where("ST_Distance(location, ST_GeomFromText('POINT (#{lng} #{lat})', #{SRID})) < ?", max_distance) .order("ST_Distance(location, ST_GeomFromText('POINT (#{lng} #{lat})', #{SRID}))") 位置。 其中(“S

因此,我有一个空间查询,根据给定的lat/lng获取用户的位置。查询如下所示:

Location.
  where("ST_Distance(location, ST_GeomFromText('POINT (#{lng} #{lat})', #{SRID})) < ?", max_distance)
  .order("ST_Distance(location, ST_GeomFromText('POINT (#{lng} #{lat})', #{SRID}))")
位置。
其中(“ST#u距离(位置,ST#u GeomFromText('POINT(#{lng}{lat}),#{SRID}))<?,最大距离)
.order(“ST#u距离(位置,ST#u GeomFromText('POINT(#{lng}}{lat}),#{SRID})))
因为这里的lat/lng是用户的lat/lng,DB正在对每个记录执行距离查询。如何保存此结果以供以后使用?在我看来,我显示了距离,后来我不得不以一种慢得多的方式重新计算距离


存储该阶方程结果的最佳方法是什么

编辑:我误解了你的问题,所以请重新写下:

将查找存储为模型上的方法(我假设所有值都存储在用户表中,但我没有使用SRID,因此如果未保存这些值,请随意修改):

class用户

然后假设您正在使用Desive,或以其他方式通过查找定义用户,您可以在任何控制器操作中通过调用
current\u user.location\u lookup
调用此函数,或在需要时传递参数。在缓存和将其存储为实例变量之间,我认为它不会像单个用户那样频繁地影响数据库。

如果要将此数据存储在数据库中,则需要一个新表,因为在用户或位置表上存储都不起作用,因为用户和他们可能的位置之间存在多对多关系

您可以创建一个新的
距离
表,该表具有
用户id
位置id
、和
距离
,并使用rails中的关联进行设置:

class User
  has_many :distances
end
然后查询与用户的距离:

current_user.distances.where("distance < 5").order("distance")
当前用户距离。其中(“距离<5”)。顺序(“距离”)
不过,在您的情况下,不需要存储在数据库中,因为您只需要请求其余部分可用的数据。可以通过选择模型中的另一列(计算列)来执行此操作,该列将“持久化”到视图中:

Location
  .select("*")
  .select("ST_Distance(location, ST_GeomFromText('POINT (#{lng} #{lat})', #{SRID}) AS distance_from_user")
  .where("distance_from_user < ?", max_distance)
  .order("distance_from_user")
位置
。选择(“*”)
.选择(“ST#u距离(位置,ST#u GeomFromText('POINT(#{lng}}{lat})”,#{SRID})作为与用户的距离)
其中(“与用户的距离<?”,最大距离)
.订单(“与用户的距离”)

然后在您看来,使用
distance\u from\u user
就像使用任何其他属性一样:

我得到了一个解决方案,它可以按照我的要求使用
选择as

Location.
  .select("*, ST_Distance(location, ST_GeomFromText(#{point}, #{SRID})) AS distance_from_user")
  .where("ST_Distance(location, ST_GeomFromText('POINT (#{lng} #{lat})', #{SRID})) < ?", max_distance)
  .order("distance_from_user")
位置。
.选择(“*,ST_距离(位置,ST_GeomFromText(#{point},#{SRID}))作为距离_到_用户”)
.式中(“ST#U距离(位置,ST#U GeomFromText('POINT(#{lng}{lat}),#{SRID}))<?,最大距离)
.订单(“与用户的距离”)

这使我能够在视图中调用
location.distance\u from\u user
,并获取在DB中计算的值。

您需要保留计算结果多长时间?计算结果与再次使用之间会发生什么情况?@OneWorking耳机我希望在视图中使用它。因此,我将获得从用户处获取lat/lng,使用它们从数据库获取位置,然后显示这些位置,还显示从用户到位置的距离。我的理解是,在SQL中,您可以执行计算并将其存储在变量名中。是否可以使用此计算进行此操作,然后使用它进行排序,还可能分配在计算位置上的虚拟属性时?为什么我不能在数据库中执行某些操作?例如,如果我执行
user=user。选择(“*,users.id作为另一个\u id”).last
,我现在将用户id设置为
user.id
user。另一个id
。ActiveRecord会自动为该选择创建一个属性。我想以某种方式使用它来执行计算,对其排序,然后选择它,以便将其分配给传递到视图的每个记录。抱歉,我误解了您的问题。请参阅编辑,doe这对你有用吗?我不想将其存储在数据库中,因为这没有任何意义,用户发送完全相同的lat/lng的机会接近于零。相反,它应该为每个请求动态计算。关键是,数据库已经在进行计算,并且比Ruby快得多。因此,与其进行在数据库中计算
顺序
,只需扔掉它,然后在Ruby中重新计算相同的东西,我正在寻找一个解决方案来保存数据库计算并使用它。@PeterR然后查看我的解决方案的第二部分,它包括在计算中,并选择它,因此它是模型的“一部分”(其工作原理与任何其他属性相同)。您可以在视图中重用
distance\u from\u user
,而无需重新计算。
Location.
  .select("*, ST_Distance(location, ST_GeomFromText(#{point}, #{SRID})) AS distance_from_user")
  .where("ST_Distance(location, ST_GeomFromText('POINT (#{lng} #{lat})', #{SRID})) < ?", max_distance)
  .order("distance_from_user")