我正在使用地理编码器,并且有一个名为Location的模型。这个模型包含经度、纬度和地址。我想让用户选择填写经度和纬度或地址。如果其中一个已填充,则填充其余信息。我做了什么
before_validation :check
def check
if self.address.blank?
reverse()
else
geo()
end
end
def reverse
reverse_geocoded_by :latitude, :longitude,
:address => :address
after_validation :reverse_geocode
end
def geo
geocoded_by :address
after_validation :geocode
end
但我得到了以下undefined method reverse_geocoded_by
,我不知道该怎么办!
不能在实例方法内部调用类方法。请记住,geocoded_by
可能是为您的模型类定义的。您不能在不影响模型的所有实例的情况下任意更改一个实例的验证,因此这通常被视为一个坏主意。
您最好拥有一个"Location"模型,该模型可以通过两种不同的方式之一进行地理编码,并为每种编码类型创建一个子类。也就是说,可以为每一个独立地建立规则。使用单表继承(STI)可以很容易地存储这些信息。
所以你可以有:
class Location < ActiveRecord::Base
end
class ForwardLocation < Location
geocoded_by :address
after_validation :geocode
end
class ReverseLocation < Location
reverse_geocoded_by :latitude, :longitude,
:address => :address
after_validation :reverse_geocode
end
然后你会相应地添加正确的位置:
self.location = self.address? ? ReverseLocation.create(...) : ForwardLocation.create(...)
您也可以编写方法来更直接地处理填充字段,而不是像这样使用子类,但这完全取决于您接收和处理的数据类型。
通常,一个类应该只有一组before/after回调。如果回调定义支持:if
样式的声明,则可以有条件地触发其中一些回调。有时,您需要编写自己的before_validation
例程来处理更奇特的需求。