更正地理编码器验证的回调



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

对于一个小型制图项目,我们使用地理编码器 gem。我们有一个模型Place包含:street:house_number:postal_code:city:address包装为一个简单的字符串,作为传递给地理编码器的虚拟属性。我们正在使用 nominatim (-> OSM 数据)进行查询。与谷歌API不同,如果给定的地址不对应于纬度/纬度对,则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 在被评估引发验证错误(不存在)之前将为 nil。到目前为止,这适用于创建新位置,但我无法修改验证以使其适用于控制器内的update操作。基本上,我想检查应用于address的更改是否有效(即 API 是否找到到给定地址的纬度/纬度对)。研究我发现的文档,我做了一个像before_validate :geocode, if: :address_changed?这样的条件回调,但由于更新请求的参数在我的模型中不可用,我不知道如何检查它。我会很高兴任何提示!

编辑:

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

模型无需知道参数即可更新请求。您可以通过检查构成地址的任何列是否已更改来检查地址是否已更改。由于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 都需要是列才能使上述内容正常工作。

最新更新