在rails中调用方法的最佳方法

时间:2018-05-30 23:20:34

标签: ruby-on-rails postgis

我遇到了一些问题,而且我不知道这是解决问题的最佳方法。

我有一个方法,我想在两个视图中帮助它: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 =距离bewtveen 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"
])

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

表pois:

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

表格曲目:

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

曲目has_many pois Poi belongs_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?

1 个答案:

答案 0 :(得分:0)

假设您有@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)