【发布时间】:2020-09-18 21:00:25
【问题描述】:
如 GeoKit 指南 https://github.com/geokit/geokit-rails#using-through 中所述,我正在尝试查找订单“pickup_address”范围内的所有驱动程序
司机通过 UserLocations 获得位置,而订单通过 PickupAddresses 获得位置。
我收到以下错误:
NoMethodError in OrdersController#show
undefined method `lat' for "Order"
订单.rb
class Order < ApplicationRecord
has_paper_trail
# an order MUST contain the following
validates_presence_of :description
validates_presence_of :weight
validates_presence_of :length
validates_presence_of :width
validates_presence_of :height
validates_presence_of :pickup_address
validates_presence_of :dropoff_address
validates_presence_of :pickup_contact
validates_presence_of :dropoff_contact
# each order should have one address for pickup and one address for dropoff
has_one :pickup_address, :as => :locatable # also works for belongs_to associations
acts_as_mappable :through => :pickup_address
has_one :dropoff_address, inverse_of: :order
# each order needs two contacts
has_one :pickup_contact, inverse_of: :order
has_one :dropoff_contact, inverse_of: :order
end
PickupAddress.rb
class PickupAddress < Address
belongs_to :locatable, :polymorphic => true
acts_as_mappable
end
我还将acts_as_mappable 添加到Address.rb 以查看代码是否可以工作,但没有任何改变。
class Address < ApplicationRecord
belongs_to :locatable, :polymorphic => true
acts_as_mappable
# Attributes to have a valid address for Driver/Geocoder
validates_presence_of :street1
validates_presence_of :city
validates_presence_of :state
validates_presence_of :country
validates_presence_of :postal
validates_presence_of :type
# Geocoder conversion for easier calculations
geocoded_by :full_address
after_validation :geocode
# address used by Geocoder and condensed display
def full_address
[street1, city, state, country].compact.join(', ')
end
end
这是我遇到错误的行:
@drivers = Driver.within(5, :origin => @order)
并且,作为参考,这是我的驱动程序映射:
驱动程序.rb
class Driver < User
has_many :orders
end
用户.rb
class User < ApplicationRecord
# each user has a location, drivers first, then can expand later
has_one :user_location, :as => :locatable
acts_as_mappable :through => :user_location
end
用户位置.rb
class UserLocation < ApplicationRecord
belongs_to :locatable, :polymorphic => true
acts_as_mappable :default_units => :miles
#reverse_geocoded_by :latitude, :longitude
end
最后是架构:
create_table "user_locations", force: :cascade do |t|
t.integer "user_id"
t.float "lat"
t.float "lng"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_user_locations_on_user_id", using: :btree
end
create_table "addresses", force: :cascade do |t|
t.string "type"
t.string "street1"
t.string "street2"
t.string "city"
t.string "state"
t.string "postal"
t.string "country"
t.integer "order_id"
t.float "lat"
t.float "lng"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["order_id"], name: "index_addresses_on_order_id", using: :btree
end
OrdersController.rb
class OrdersController < ApplicationController
layout 'dashboard'
before_action :authenticate_user!
before_action :set_order, only: [:show, :edit, :update, :destroy]
before_action :load_resource
# insert generic boring stuff
private
# Use callbacks to share common setup or constraints between actions.
def set_order
@order = Order.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def order_params
params.require(:order).permit(:invoice, :description, :weight, :length, :width, :height, :account_id, :driver_id, :status,
pickup_address_attributes: [:street1, :street2, :city, :state, :postal, :country],
dropoff_address_attributes: [:street1, :street2, :city, :state, :postal, :country],
pickup_contact_attributes: [:first_name, :last_name, :phone],
dropoff_contact_attributes: [:first_name, :last_name, :phone])
end
def load_resource
case params[:action].to_sym
when :show
if current_user.is_admin?
@drivers = Driver.within(5, :origin => @order)
end
end
end
end
使用 'lat' 和 'lng' 更改我的纬度和经度列后出现新错误:
NEW error: PG::UndefinedTable: ERROR: missing FROM-clause entry for table "user_locations"
LINE 1: ...M "users" WHERE "users"."type" IN ('Driver') AND (user_locat...
^
: SELECT "users".* FROM "users" WHERE "users"."type" IN ('Driver') AND (user_locations.lat IS NOT NULL AND user_locations.lng IS NOT NULL) AND (user_locations.lat>29.61103991439227 AND user_locations.lat<38.28523108560773 AND user_locations.lng>-88.97349091777367 AND user_locations.lng<-78.5259326822263) AND (((ACOS(least(1,COS(0.5925067393881714)*COS(-1.4617082185063466)*COS(RADIANS(user_locations.lat))*COS(RADIANS(user_locations.lng))+ COS(0.5925067393881714)*SIN(-1.4617082185063466)*COS(RADIANS(user_locations.lat))*SIN(RADIANS(user_locations.lng))+ SIN(0.5925067393881714)*SIN(RADIANS(user_locations.lat))))*3963.1899999999996) <= 300))
【问题讨论】:
-
我离开了指南,位于此处:github.com/geokit/geokit-rails
-
您需要提供订单控制器。
-
为你添加了控制器!
-
但是pickup_address没有lat和lng属性,怎么知道提货地址点?
-
取货地址确实有 lat 和 lng 属性。
标签: ruby-on-rails ruby geokit