导轨模型中的两种方式的地址代码

问题描述:

我使用地理编码器,并有一个称为位置的模型。该模型包含经度,纬度和地址。我想要的是给用户选择填写经度和纬度或地址。如果其中一个填满,则填写剩余的信息。所以在这里我做了什么导轨模型中的两种方式的地址代码

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可能是为您的模型类定义的。你不能任意改变一个实例的验证而不影响模型的所有实例,所以这通常被认为是一个坏主意。

对于可以用两种不同方式进行地理编码的“位置”模型,并为每种编码类型创建一个子类,可能会更好。也就是说,这些规则可以独立地为每一个建立。使用单表继承(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(...) 

你也可以编写处理更直接填充字段不必使用子类方法像这样,但它完全取决于你正在接收和处理的数据种类。

通常,一个类应该只有一组前/后回调。如果回调定义支持:if样式声明,则可以有条件地触发某些回调。有时你需要编写自己的例程来处理你更奇特的需求。

+0

我唯一的担心,抱歉,但我仍然是新的红宝石,是self.location = .... ReverseLocation.create(...)它是如何定义的?是在我的模型中,我的控制器,如果它在我的模型中,那么我将需要在正确的位置定义类型 – Jseb 2013-02-11 01:57:21

+0

它可能是控制器或模型,具体取决于您的应用程序设计。分别捕获位置参数,构造适当类型的位置对象,然后将其分配给具有与其关联的位置的记录可能是有利的。 – tadman 2013-02-11 02:19:38