2016-04-27 9 views
1

Ich hoffe, das ist kein Dupe, aber da ich bisher keine befriedigende Antwort gefunden habe, werde ich meine Frage stellen. Ich bin ein Schienen Anfänger also bitte sei sanft zu mir;)Korrekte Rückrufe für Geocoder Validierung

Für ein kleines Kartierungsprojekt verwenden wir Geocoder gem. Wir haben ein Modell Place, das :street, :house_number, :postal_code, :city enthält, als einfache Zeichenfolge von :address als das virtuelle Attribut eingewickelt, das an Geocoder übergeben wird. Wir führen die Abfrage mit nominatatim (-> OSM data) durch. Im Gegensatz zur Google-API gibt nominatim nil zurück, wenn die angegebene Adresse keinem Lat/Lon-Paar entspricht. Bisher haben sich unsere Modelldatei sieht wie folgt aus

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 

Im Gegensatz zu den meisten Beispielen ich sah ich habe before_validation :geocode bin mit, weil sonst lat und lon Null sein würde, bevor sie ausgewertet werden Sie jetzt ein Validierungsfehler erhöhen (nicht vorhanden) . Bis jetzt funktioniert das zum Erstellen neuer Orte, aber ich kann die Validierung nicht ändern, damit sie für die Aktion update in meinem Controller funktioniert. Grundsätzlich möchte ich überprüfen, ob die Änderungen gültig sind, die auf address gültig sind (d. H. Ob die API ein lat/lon-Paar zu der gegebenen Adresse findet). Beim Studieren der Dokumentation habe ich festgestellt, dass ich einen bedingten Rückruf wie before_validate :geocode, if: :address_changed? mache, aber da die Parameter der Update-Anfrage in meinem Modell nicht verfügbar sind, habe ich keine Ahnung, wie ich das überprüfen soll. Ich würde mich über jeden Hinweis freuen!

edit:

akzeptierte Antwort unten rechts ist, funktioniert nicht sofort, weil in meinem Controller mir update statt update_attributes verwenden.

Antwort

0

Ihr Modell muss die Parameter zum Aktualisieren der Anforderung nicht kennen. Sie können überprüfen, ob sich die Adresse geändert hat, indem Sie überprüft haben, ob sich eine der Spalten Ihrer Adresse geändert hat. Da address keine Spalte ist, müssen Sie address_changed? wie so definieren:

before_validation :geocode, if: :address_changed? 

def address_changed? 
    street_changed? || house_number_changed? || postal_code_changed? || city_changed? 
end 

Beachten Sie, dass street, house_number, city und postal_code werden alle arbeiten für die oben genannten Spalten, um sein müssen.

+0

Dies funktioniert nicht. Ich nehme an, "* _changed?" Sind Hilfsmethoden? Woher kommen sie? –

+0

Es ist keine Hilfsmethode, es wird von Rails definiert. Die Konvention ist, dass eine Instanzmethode ' _changed?' Für jede Spalte in Ihrem Modell definiert ist und True zurückgibt, wenn dieser Spaltenwert entweder zum ersten Mal gesetzt wird oder sich seit der letzten Speicherung geändert hat. –

+0

Ok, danke. In der Konsole kann ich diese Methoden testen, sie funktionieren. Trotzdem funktionieren sie nicht im Kontext der vorgeschlagenen Methode "address_changed", die im bedingten Callback verwendet wird. Ich kann immer noch fehlerhafte Einträge "aktualisieren", ohne dass sie geocodiert werden (was zu einem Fehler führen würde). Irgendeine Idee? –