【问题标题】:Correct callbacks for geocoder validation正确的地理编码器验证回调
【发布时间】:2016-04-27 14:27:14
【问题描述】:

我希望这不是一个骗局,但由于到目前为止我还没有找到令人满意的答案,所以我要提出我的问题。我是 Rails 初学者,所以请对我温柔一点;)

对于一个小型地图项目,我们正在使用地理编码器 gem。我们有一个模型Place,其中包含:street:house_number:postal_code:city,由:address封装为一个简单的字符串,作为传递给地理编码器的虚拟属性。我们正在使用 nominatim(-> OSM 数据)进行查询。与 google API 不同,如果给定的地址不对应于 lat/lon 对,则 nominatim 返回 nil。到目前为止我们的模型文件是这样的

class Place < ActiveRecord::Base
  has_many :descriptions, :dependent => :delete_all
  accepts_nested_attributes_for :descriptions

  geocoded_by :address
  before_validation :geocode

  validates :address, presence: true
  validates :name, presence: true
  validates :longitude, presence: true,
                        numericality: { less_than_or_equal_to: 90, greater_than_or_equal_to: -90 }
  validates :latitude, presence: true,
                       numericality: { less_than_or_equal_to: 180, greater_than_or_equal_to: -180 }
  validates :categories, presence: true

  def address
    ["#{self.street} #{self.house_number}", self.postal_code, self.city].join(', ')
  end
end

与我看过的大多数示例不同,我使用的是before_validation :geocode,因为否则 lat 和 lon 在被评估之前将为零,从而引发验证错误(不存在)。 到目前为止,这适用于创建新位置,但我无法修改验证以使其适用于我的控制器内的 update 操作。基本上我想检查应用于address 的更改是否有效(即API 是否找到给定地址的纬度/经度对)。研究我发现的文档,我做了一个条件回调,比如before_validate :geocode, if: :address_changed?,但由于更新请求的参数在我的模型中不可用,我不知道如何检查。任何提示我都会很高兴!

编辑:

下面接受的答案是正确的,没有立即工作,因为在我的控制器内部我使用的是update 而不是update_attributes

【问题讨论】:

    标签: ruby-on-rails rails-geocoder


    【解决方案1】:

    您的模型不需要知道更新请求的参数。您可以通过检查构成您的地址的任何列是否已更改来检查地址是否已更改。由于address 不是列,您需要像这样定义address_changed?

    before_validation :geocode, if: :address_changed?
    
    def address_changed?
      street_changed? || house_number_changed? || postal_code_changed? || city_changed?
    end
    

    请注意,streethouse_numbercitypostal_code 都需要为列,才能使上述操作生效。

    【讨论】:

    • 这不起作用。我假设*_changed? 是辅助方法?他们来自哪里?
    • 它不是辅助方法,它是由 Rails 定义的。约定是为模型中的每一列定义一个实例方法&lt;column_name&gt;_changed?,如果该列值是第一次设置,或者自上次持久化以来已更改,则该方法将返回true。
    • 好的,谢谢。在控制台中我可以测试这些方法,它们有效。然而,它们在条件回调中使用的建议的address_changed? 方法的上下文中不起作用。我仍然可以update 格式错误的条目而无需对其进行地理编码(这会引发错误)。有什么想法吗?
    • 好的,我正在解决问题...在我的控制器中调试 update 方法显示,虽然参数传递正确并且更改已应用 - *_changed? 返回 false ...
    • 你还在用before_validation :geocode, if: :address_changed?吗?
    猜你喜欢
    • 2017-04-24
    • 2021-10-22
    • 2021-11-23
    • 2012-01-06
    • 2016-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多