Class attribute VS constant (fr)
J’ai récemment eu deux problèmes avec les constantes définies dans une classe :
- Problème de définitions multiples à cause de l’utilisation de concerns et de gems (plusieurs engines définis dans des gems utilisaient le meme concern où une contante était défnie).
 - Problème lors de l’héritage.
 
Exemple :
class Base
  DEFAULT_VALUES = { key: 'value1', key2: 'value2' }
end
class Extended < Base
  # WRONG : change the value of Base::DEFAULT_VALUES
  # DEFAULT_VALUES[:key2] = 'Extended value2'
  # GOOD : work but does not fix the first issue
  DEFAULT_VALUES = Base::DEFAULT_VALUES.merge(key2: 'Extended value2')
endJ’ai donc opté pour l’utilisation de class_attribute présent depuis rails 3.
Avantages :
- On est sûr que le class_attribute ne sera initialisé qu’une seule fois.
 - On peut surdéfinir le class_attribute sans problème après en avoir hérité.
 
Note : Attention au array et au hash en cas de redéfinition.
class Base
  class_attribute :default_values
  self.default_values = { key: 'value1', key2: 'value2' }
end
class Extended < Base
  self.default_values = default_values.merge(key2: 'value2 custom')
end
Base.default_values  # {:key=>"value1", :key2=>"value2"}
Extended.default_values  # {:key=>"value1", :key2=>"value2 custom"}