ActiveWeekly #3
- François
Troisième et dernière semaine d’ActiveDaily, une astuce quotidienne sur ActiveSupport et ActiveModel.
Vous pouvez suivre l’ActiveDaily sur github ou bien lire ces billets de blog hebdomadaire.
Cette semaine on se concentre sur ActiveModel, alors on installe un nouveau joyau:
gem install activemodel
Et puis on essaie de l’inclure.
require 'active_model' # Un underscore mais pas de /all
ActiveModel est la base d’ActiveRecord mais aussi de mongoid, tire, datamapper, redis_orm, …
ActiveModel::Callbacks
Si les callbacks d’ActiveSupport sont un peu rude, ceux d’ActiveModel sont plus sympa.
require 'active_model'
class Bim
extend ActiveModel::Callbacks
# On déclare les callbacks disponibles
define_model_callbacks :kick
# L'implémentation
def kick
run_callbacks :kick do
puts 'BIMMMMMMMMM!'
end
end
end
class Norris < Bim
# on rajoute les callbacks
before_kick :before_kick
after_kick :after_kick
# on peut aussi utiliser around_kick :ma_methode
def before_kick
puts 'Be careful'
end
def after_kick
puts 'KO'
end
end
chuck = Norris.new
chuck.kick # Your are KO baby
Alors n’hésitez pas a rajouter des callbacks dans vos classes.
http://rubydoc.info/gems/activemodel/3.1.1/ActiveModel/Callbacks
ActiveModel::Observer
Les observers permettent de réagir à des actions d’une autre classe. Cela permet de découpler facilement deux composants. Dans la class Observé, il faut simplement appelé notify_observers.
require 'active_model'
class Norris
include ActiveModel::Observing
def kick
notify_observers(:before_kick)
puts 'BIMMMMMMMMM!'
notify_observers(:after_kick)
end
end
class NorrisObserver < ActiveModel::Observer
def before_kick(norris)
puts "start the video recording"
end
def after_kick(norris)
puts "switch off the video recording"
end
end
Norris.observers = NorrisObserver
Norris.instantiate_observers
chuck = Norris.new
chuck.kick
On arrive rapidement a avoir un comportement similaire. Seule petite déconvenue, je pensais que ActiveModel::Observing se branchait sur les callbacks.
http://rubydoc.info/gems/activemodel/3.1.1/ActiveModel/Observer http://rubydoc.info/gems/activemodel/3.1.1/ActiveModel/Observing/ClassMethods
ActiveModel::MassAssignmentSecurity
MassAssignmentSecurity permet de protéger l’écriture de certains attributs en fonction du rôle. MassAssignmentSecurity fournit deux facons de se protéger. Avec attr_accessible en mode whitelist ou avec attr_protected en mode blacklist.
require 'active_model'
class Norris
include ActiveModel::MassAssignmentSecurity
attr_accessible :name
attr_accessible :name, :guns, :as => :chuck_norris
def update(params, role=:default)
sanitize_for_mass_assignment(params, role)
end
end
chuck = Norris.new
p chuck.update({name: 'chuck', guns: 2}) # {name: 'chuck'}
p chuck.update({name: 'chuck', guns: 2}, :chuck_norris) # {name: 'chuck', guns: 2}
http://rubydoc.info/gems/activemodel/3.1.1/ActiveModel/MassAssignmentSecurity/Cla
ActiveModel::Dirty
Dirty vous aide a tracer les changements dans un objet.
require 'active_model'
class Norris
include ActiveModel::Dirty # Chuck Norris cannot be dirty, should throw an exception
define_attribute_methods [:first_name]
attr_reader :first_name
def first_name=(val)
first_name_will_change! unless val == @first_name
@first_name = val
end
end
chuck = Norris.new
chuck.first_name = 'plop'
chuck.changes
chuck.changed_attributes
Vous avez ainsi accès à quelques méthodes:
chuck.changed? # true
chuck.first_name_changed? # true
chuck.first_name_was # nil
http://rubydoc.info/gems/activemodel/3.1.1/ActiveModel/Dirty
C’est le dernier ActiveDaily. Je préfère m’arrêter sur un numéro 13.
Vous avez raté:
- des choses dans ActiveModel::AttributeMethods utilisé entre autre par ActiveModel::Dirty
- ActiveSupport::Concern qui facilite l’écriture de mixins.
- ActiveSupport::Inflector qui permet de transformer des mots du singulier au pluriel et d’autres truc aussi
- Hash#except, l’inverse de Hash#slice
- ActiveSupport::Notifications avec lequel je n’ai pas encore joué
Have a comment? Contact me by email.