2015-04-23 1 views
0

J'essaye de géocoder une adresse et j'essaye de géocoder sur un attribut non persistant appelé full_address. Voici mon code:Ordre des callbacks before_save dans les rails

class Company < ActiveRecord::Base 
    include ActiveModel::Dirty 

    validates :name, :organization, :title, :state, :city, presence: true 
    validates :email, presence: true, length: { maximum: 255 }, 
        format: { with: /\A[\w+\-.][email protected][a-z\d\-.]+\.[a-z]+\z/i, } 

    before_save :full_address 
    geocoded_by :full_address 

    before_save :geocode, if: ->(obj){obj.full_address.present? && (obj.city_changed? || obj.state_changed?)} 

    def full_address 
    "#{city}, #{state}" 
    end 
end 

 Je ne sais pas si mes callbacks before_save tirent le dans le bon ordre. Fondamentalement, comment puis-je m'assurer que le

before_save :full_address 

se déclenche avant l'autre? J'ai regardé dans la documentation de around_save, mais je ne sais toujours pas ce que ça fait.

Répondre

1

Jwan -

callbacks AR sont utilisés pour beaucoup de raisons, et ils sont particulièrement utiles pour traiter les dossiers dans la base de données, mais vous ne ont pas besoin ici pour pour « full_address ». Pourquoi? Parce que tout ce qu'il fait est de retourner une chaîne, ne pas effectuer une opération sur la base de données ou modifier les données de quelque façon que ce soit.

Cela fait un moment que j'ai travaillé avec geocoder gem, mais dans votre autre callback before_save, vous passez un lambdha pour une opération conditionnelle.

choses Couple:

1.) Vous vérifier la présence d'une chaîne interpolée, mais la validation de la présence des deux attributs interpolés, qui se déclenche avant le rappel, alors obj.full_address.present? devrait toujours revenir true parce qu'il soufflera sur les validations si les deux ou même un de ces attributs n'est pas présent. Essayez

before_save :geocode, if: ->(obj){ obj.city_changed? || obj.state_changed? }

+1 bien sur ActiveModel :: mise en œuvre sale! 2. À moins que vous n'utilisiez une version beaucoup plus ancienne de Rails ou que vous la configuriez explicitement, ActiveModel::Dirty est automatiquement chargé; pas besoin de line 2.

3.) J'essaierais aussi d'utiliser un callback after_validation au lieu de before_save. Ne peut pas garantir que cela résoudra le problème, mais il est plus tôt dans la pile de rappel. Voir http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html