2017-09-26 4 views
0

Je souhaite déplacer ma méthode downcase_email hors de ma classe User car plusieurs classes doivent être redimensionnées. Je ne suis pas sûr si c'est la bonne approche, mais j'ai créé un module et déplacé la méthode dedans.Comment faire pour référencer les attributs de modèle dans les méthodes d'instance de module dans RoR 5

class User < ApplicationRecord 
    include ModelUtilities 

    before_save :downcase_email 

    # downcase_email was previously here 
    # 
    # def downcase_email 
    # self.email = email.downcase 
    # end 
end 
fichier

dans lib/model_utilities.rb

module ModelUtilities 

    def downcase_email 
    self.email = email.downcase 
    end 

end 

Quand je lance le code, je reçois l'erreur suivante:

NoMethodError (undefined method `downcase' for nil:NilClass): 

lib/model_utilities.rb:6:in `downcase_email' 

Toute aide serait appréciée!

+1

'self.email = email.downcase si email.present? '. Aussi, il vaut mieux utiliser le rappel 'before_validation', pas' before_save'. Et ne downcasing que si le courrier électronique est chaged, pas tout le temps. 'before_validation: downcase_email, si:: email_changed?' – chumakoff

+0

@xlembouras C'est. L'erreur serait sur "include" si c'était le problème :) – P0lska

+0

vérifier ce qui vient en soi et utiliser self.email.downcase au lieu de email.downcase –

Répondre

0

Vous faites tout correctement. Mais qu'en est-il du scénario lorsque l'email lui-même est vide/nul? Ensuite, vous obtiendrez 'méthode non définie downcase pour la classe zéro'

Il suffit donc de modifier votre code comme celui-ci

nil.try(:something) wont throw error - its like mini exception handler

def downcase_email 
    self.email = email.try(:downcase) 
end 
+0

Accepter cela car c'était exactement ce que le problème était ... Je suis descendu un trou de lapin! – P0lska

+0

@ P0lska vous êtes les bienvenus – krishnar

3

C'est une bonne approche commune, mais Rails propose des préoccupations pour ce cas. http://api.rubyonrails.org/v5.1/classes/ActiveSupport/Concern.html

Dans votre cas, le code sera:

# file in models/concerns/model_utilities.rb 

module ModelUtilities 
    extend ActiveSupport::Concern 

    included do 
    before_validation :downcase_email 
    end 

    def downcase_email 
    email.downcase! 
    end 

end 


# include your concern 
class User < ApplicationRecord 
    include ModelUtilities 
end 

Regardez before_validation peut être déplacé à l'inquiétude.