0

私が持っているのは、トラック運転手がそこに利用可能なトラックを投稿するようになるトラック輸送ボードです。トラックスの投稿があります。しかし、検索機能の設定と、異なるテーブルを関連付ける方法に問題があります。

Rails 3
postgres

gem 'geokit-rails'

私が今持っている方法は、次のようなロケーションテーブルのセットアップがあることです:

 class Location < ActiveRecord::Base

  attr_accessible :cs, :lat, :lon, :city, :state

  acts_as_mappable :default_units => :miles,
                   :default_formula => :sphere,
                   :distance_field_name => :distance,
                   :lat_column_name => :lat,
                   :lng_column_name => :lon

誰かがトラックを投稿すると、出発地と目的地があります。そのため、2 つの場所があり、次のように設定されています。

class Truck < ActiveRecord::Base
  attr_accessible :available, :company_id, :dest_id, :origin_id, :equipment, :origin, :dest
  belongs_to :origin, class_name: "Location", foreign_key: :origin_id
  belongs_to :dest, class_name: "Location", foreign_key: :dest_id
  belongs_to :company

私が設定した方法で、次の場所から位置情報を取得できます。

Truck.find(1).origin  || Truck.find(1).dest

それに関連付けられた Location レコードを返します。

今私の問題は、検索関数を作成して、原点から「指定された」距離内にあるトラックを見つけられるようにしたいということです || 宛先 || 出発地と目的地

すべての場所を検索し、 Springfield Location.within(25, :origin => "Springfield, Mo")Mo から 25 マイル以内にある場所を返します。

しかし、2 つの場所 (出発地と目的地) があり、それらが場所 ID に関連付けられているトラックでこれを使用するにはどうすればよいでしょうか。

現在、他のいくつかの検索パラメーターが既にコード化されており、これをどのように組み込むことができるかわかりません。

def search(search)
    where = []
    where << PrepareSearch.states('dest', search.dest_states) unless search.dest_states.blank?
    where << PrepareSearch.states('origin', search.origin_states) unless search.origin_states.blank?
    where << PrepareSearch.location('origin', search.origin_id, search.radius) unless search.origin.blank?
    where << PrepareSearch.location('dest', search.dest_id, search.radius) unless search.dest.blank?
    where << PrepareSearch.equipment(search.equipment) unless search.equipment.blank?
    where << PrepareSearch.date('available', search.available, '<') unless search.available.blank?
    where = where.join(' AND ')
    Truck.where(where)
  end


module PrepareSearch
    def PrepareSearch.location(type, location, radius)
      loc = Location.find(location)

   *type will be origin/destination Location active record
   *location will be Location id
   *radius will be a given mileage

**This is where i need to figure out what to put here**

    end
end

方程式を組み込むだけの方がよいでしょうか。

 def sphere_distance_sql(origin, units)
    lat = deg2rad(origin.lat)
    lng = deg2rad(origin.lng)
    multiplier = 3963.1899999999996 # for miles

    sphere_distance_sql(lat, lng, multiplier)
  end
  def sphere_distance_sql(lat, lng, multiplier)
    %|
      (ACOS(least(1,COS(#{lat})*COS(#{lng})*COS(RADIANS(#{qualified_lat_column_name}))*COS(RADIANS(#{qualified_lng_column_name}))+
      COS(#{lat})*SIN(#{lng})*COS(RADIANS(#{qualified_lat_column_name}))*SIN(RADIANS(#{qualified_lng_column_name}))+
      SIN(#{lat})*SIN(RADIANS(#{qualified_lat_column_name}))))*#{multiplier})
     |
  end
4

1 に答える 1

1

さて、私は自分の問題の解決策を見つけました...もっと良い解決策があれば、知りたいです。

where << PrepareSearch.location_ids("origin", search.origin, search.radius) unless search.origin_id.blank?
where << PrepareSearch.location_ids("dest", search.dest, search.radius) unless search.dest_id.blank?


def PrepareSearch.location_ids(type, location, radius)
  if location.nil?
    return nil
  else
    loc = Location.find(location)
    location(type, loc, radius)
  end

end

def PrepareSearch.location(type, location, radius)
  locs = Location.within(radius, :origin => location.cs).pluck(:id)
  st = ""
  locs.each {|s| st += "'#{s}'," }
  st = st[0..-2]
  "#{type}_id IN (#{st})"
end
于 2014-12-30T21:24:01.533 に答える