下面是我的类,我正在使用地理编码器。我有困难,检查是否地址,通过地理编码器是有效的。当我添加一个公司/编辑一个有地址的公司时,这段代码工作得很好。但是,我需要代码才能工作,所以当用户试图在编辑或创建公司时放置一个不提供纬度和经度的地址时,会弹出一个错误并通知用户地址无效。
模型
class Company < ActiveRecord::Base
validates :name, presence: true, length: { maximum: 30 }
validates :website, presence: true
validates :address, presence: true
validates :description, presence: true
validates :primary_field, presence: true
geocoded_by :address
before_save :geocode, if: ->(obj){ obj.address.present? and obj.address_changed? }
after_save :set_popup_value
private
...
end视图
<% provide(:title, 'Add Company') %>
<h1>Add Company</h1>
<div class="row">
<div class="span6 offset3">
<%= form_for(@company) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :website %>
<%= f.text_field :website %>
<%= f.label :primary_field %>
<%= f.select :primary_field, @primary_field %>
<%= f.label :address %>
<%= f.text_field :address, :placeholder => '123 Test St, City State Zip'%>
<%= f.label :description %>
<%= f.text_area :description, :size => "30x5" %>
<%= f.submit "Add Company", class: "btn btn-large btn-primary" %>
<% end %>
</div>
</div>发布于 2014-04-18 05:09:28
所以,经过几天的努力,我想出了几个解决方案。第一个确实很烦人,但我做到了我所需要的。我的第二个解决方案要优雅得多,而且从我到目前为止所知道的情况来看,效果非常好!我希望其他人发现这是有用的。
我用几行代码来处理控制器中的所有逻辑。
geocoded_by :address
after_validation :geocode, if: ->(obj){ obj.address.present? and obj.address_changed? }
after_validation :lat_changed?
after_save :set_popup_value
private
# This is used to make sure that our address is actually parsed properly and we
# get a valuable lat/long
def lat_changed?
if (self.address_changed?)
if !(self.latitude_changed?)
self.errors.add(:address, "is not valid")
return false
end
end
return true
end通过在我的地理代码之后创建另一个after_validation,我能够检查适当的值是否发生了变化,以及它们是否以某种方式发生了变化,这是我所知道的地理编码中存在的一个问题。
如果地址改变了,但纬度没有变化,比你知道的地址通过地理编码器时,它没有得到一个返回的lat/long。如果是这样的话,那么我们只需添加一个错误,抛出给用户并返回false,这将停止对数据库的保存。
我希望其他有这个问题的人能够找到这个帖子!
发布于 2017-03-15 16:13:40
您可以在下面这样的模型中进行设置,以验证address,当地址更改时,geocode只会被调用一次。在geocoded_by方法中,我们显式地设置为编写latitude和longitude,因此在找不到地址时,这些列将被设置为nil。
class Company < ActiveRecord::Base
geocoded_by :address do |object, results|
if results.present?
object.latitude = results.first.latitude
object.longitude = results.first.longitude
else
object.latitude = nil
object.longitude = nil
end
end
before_validation :geocode, if: :address_changed?
validates :address, presence: true
validates :found_address_presence
def found_address_presence
if latitude.blank? || longitude.blank?
errors.add(:address, "We couldn't find the address")
end
end
end发布于 2014-04-15 18:24:54
您可能会想要对Geo编码器服务执行web/服务调用。你如何做到这一点取决于你想要什么:近似请求或背景工作,等等。
这是一个相当普遍的问题,因此,您可能会在programmers.stackexchange.com中得到更好的支持。
但是,这里有一些帮助你解决问题的链接:
谷歌地理编码API:https://developers.google.com/maps/documentation/geocoding/?csw=1
OpenStreetMap:查找
https://stackoverflow.com/questions/23090430
复制相似问题