我希望这不是一个骗局,但是因为到目前为止我还没有找到令人满意的答案,所以我会提出我的问题。我是一名初学者,所以请温柔地对待我;)
对于小型地图项目,我们使用geocoder 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
。
答案 0 :(得分:0)
您的模型不需要知道更新请求的参数。您可以通过检查构成地址的任何列是否已更改来检查地址是否已更改。由于address
不是列,因此您需要像这样定义address_changed?
:
before_validation :geocode, if: :address_changed?
def address_changed?
street_changed? || house_number_changed? || postal_code_changed? || city_changed?
end
请注意,street
,house_number
,city
和postal_code
都需要为列,以便上述功能正常运行。