【问题标题】:best way to call a method in rails在 Rails 中调用方法的最佳方法
【发布时间】:2018-05-30 23:20:34
【问题描述】:

我有一些问题,我不知道解决问题的最佳方法是什么。

我有一个方法,我想在两个视图中提供帮助:poi.views 和 track.index

方法:

@distance_a_to_b = Track.find_by_sql(
  ["SELECT
    ST_Distance(line::geography, pta::geography) +
    ST_Distance(line::geography, ptb::geography) +
    ST_Length(ST_LineSubstring(
        line,
        least(ST_Line_Locate_Point(line, pta), ST_Line_Locate_Point(line, ptb)),
        greatest(ST_Line_Locate_Point(line, pta), ST_Line_Locate_Point(line, ptb)))::geography)  AS dst_line
    FROM (
      SELECT
        'SRID=4326;LINESTRING(1.457834243774414 43.597960902821576,1.462029218673706 43.59636807591895)'::geometry line,
        'SRID=4326;POINT(1.457994 43.598124)'::geometry pta,
        'SRID=4326;POINT(1.461628 43.596128)'::geometry ptb
    ) data"
  ])

我需要在两个视图中调用这个方法......

poi.show = A 到 poi 的距离 (point())

track.index = 每个 poi 的距离 (point())

此方法需要 3 个参数:

a = 起点(查询参数)作为 Point()

b = 作为 Point() 的终点

和一个线串或合并线串

如何将此参数发布到此方法?

有点:

 @distance_a_to_b = Track.find_by_sql(
  ["SELECT
    ST_Distance(line::geography, pta::geography) +
    ST_Distance(line::geography, ptb::geography) +
    ST_Length(ST_LineSubstring(
    line,
    least(ST_Line_Locate_Point(line, pta), ST_Line_Locate_Point(line, ptb)),
    greatest(ST_Line_Locate_Point(line, pta), ST_Line_Locate_Point(line, ptb)))::geography)  AS dst_line
  FROM (
    SELECT
    '@track.path'::geometry line,
    '@poi.lonlat'::geometry pta,
    'query: params'::geometry ptb
) data"
])

如何发布每个视图中的变量? 如何从每个视图中获取此方法的结果?通过调用方式?

表位置:

t.geography "lonlat", limit: {:srid=>4326, :type=>"st_point", :geographic=>true}

表轨道:

t.geometry "path", limit: {:srid=>4326, :type=>"line_string"}

跟踪 has_many pois Poi 属于_to track

编辑

按照建议,这就是我所做的

在 poi 控制器中(只是为了定义数据):

def index
  track = Track.friendly.find(params[:track_id])
  @pois = Poi.where(track_id: track)
  @track =  Track.find_by id: 1
  @poi = Poi.find_by id: 1

  respond_to do |format|
    format.html
end

在 poi 模型中:

 def distance_along_track_to(poi2, track)
   distance_sql = <<-SQL
    SELECT
      ST_Distance(tr.path::geography, pta.lonlat::geography) +
      ST_Distance(tr.path::geography, ptb.lonlat::geography) +
      ST_Length(ST_LineSubstring(
        tr.path,
        least(ST_Line_Locate_Point(tr.path, pta.lonlat::geometry), ST_Line_Locate_Point(tr.path, ptb.lonlat::geometry)),
        greatest(ST_Line_Locate_Point(tr.path, pta.lonlat::geometry), ST_Line_Locate_Point(tr.path, ptb.lonlat::geometry)))::geography)  AS dst_line
      FROM tracks tr, pois pta, pois ptb
      WHERE tr.id = #{track.id}
      AND pta.id = #{self.id}
      AND ptb.id = #{poi2.id}
   SQL
   Poi.find_by_sql(distance_sql).dst_line
end

在索引视图中:

<% @pois.each do |poi| %>
  <div>
    <%= poi.name %>
    <%= poi.track_id %>
    <%= @poi.distance_along_track_to(poi, @track) %> %>
 </div>
<% end %>

现在我收到了这个错误信息:

undefined method `dst_line' for [#<Poi id: nil>]:Array

我不明白为什么@poi = nil?

【问题讨论】:

  • 您能否提供更多背景信息:曲目在数据库中,对吗?这两个点是作为坐标给出的还是也存储在数据库中?你能告诉我们数据模型吗?
  • 所有数据都在数据库中。点是地理和线串几何。

标签: ruby-on-rails postgis


【解决方案1】:

假设你有@poi1, @poi2@track,你的方法可以写成如下:

class Track  

  def distance_between_two_pois(poi1, poi2) 
    distance_sql = <<-SQL 
      SELECT
        ST_Distance(tr.path, pta.lonlat) +
        ST_Distance(tr.path, ptb.lonlat) +
        ST_Length(ST_LineSubstring(
          tr.path,
          least(ST_Line_Locate_Point(tr.path, pta.lonlat), ST_Line_Locate_Point(tr.path, ptb.lonlat)),
          greatest(ST_Line_Locate_Point(tr.path, pta.lonlat), ST_Line_Locate_Point(tr.path, ptb.lonlat)))::geography)  AS dst_line
       FROM tracks tr, pois pta, pois ptb
       WHERE tr.id = #{self.id}
         AND pta.id = #{poi1.id}
         AND ptb.id = #{poi2.id} 
    SQL 
    Track.find_by_sql(distance_sql).first.dst_line
  end 
end 

然后你可以这样称呼它

@track.distance_between_two_pois(@poi1, @poi2)

不确定最好的 api 是什么?我也可以想象写类似的东西?

@poi1.distance_along_track_to(@poi2, @track) 

【讨论】:

  • 谢谢@nathanvda.. 但它不起作用。我想我离解决方案很近了......你能看看我在上面的编辑中做了什么吗?
  • 对,find_by_sql 返回一个数组/结果集。所以我们必须先得到第一个元素。相应地调整了我的答案。
  • 谢谢@nathanvda...这很好,正是我附加的内容:D 最后一个问题,我如何按距离订购? ;)
  • 你需要什么?类似于轨道上最近的 5 个地点?
  • 不完全...我想找到:所有点都围绕从 A 的 X 公里到 Y 公里之间的一条线。例如:所有点都围绕一条线(半径 1 公里)在(5 公里到 10 公里之间) km) 从城市按 dist asc 排序
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-30
  • 1970-01-01
  • 2014-01-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多