Nous savons que Rails 5 a ajouté ApplicationRecord
en tant que classe abstraite dont nos modèles ont hérité (ActiveRecord).
Mais fondamentalement, je pense que chaque exigence technique que nous faisons avec ApplicationRecord, nous pouvons également le faire avec ActiveRecord::Base
. Par exemple:
module MyFeatures
def do_something
puts "Doing something"
end
end
class ApplicationRecord < ActiveRecord::Base
include MyFeatures
self.abstract_class = true
end
Alors maintenant, chaque modèle sera attaché aux comportements de MyFeatures
. Mais nous pouvons également y parvenir en Rails 4:
ActiveRecord::Base.include(MyFeatures)
Alors, quel est l’avantage d’utiliser ApplicationRecord
, pensez-vous qu’il est nécessaire d’ajouter ApplicationRecord
?
Bien que cela puisse sembler identique dans les applications de base Rails, il existe en réalité une différence importante lorsque vous commencez à utiliser Rails moteurs, plugins/gems ou méthodes directes à partir de ActiveRecord::Base
.
ActiveRecord::Base.include(MyFeatures)
mélange les fonctionnalités directement dans ActiveRecord::Base
et il est présent à tout jamais pour toutes les utilisations ultérieures de ActiveRecord::Base
(il ne peut pas être "non mélangé") et il n'y a aucun moyen de récupère l'original ActiveRecord::Base
dans n'importe quel code après l'inclusion. Cela peut facilement entraîner des problèmes si une partie de la fonctionnalité mélangée a changé le comportement ActiveRecord par défaut ou si, par exemple, deux moteurs/gemmes ont essayé d'inclure des méthodes portant le même nom.
D'autre part, l'approche ApplicationRecord
rend les fonctionnalités présentes uniquement pour les classes (modèles) qui en héritent , les autres classes, ainsi que l'utilisation directe de ActiveRecord::Base
rester vierge, non encombré par les fonctionnalités du module.
Ceci est particulièrement important lorsque des moteurs ou des plugins Rails sont utilisés, car cela leur permet de séparer leur propre logique de modèle de la logique de modèle de l'application principale, ce qui n'était pas possible avant ApplicationRecord
.
Tout cela est aussi bien décrit dans cet article de blog et ce commentaire de github .
Ceci est pour développer la réponse de @ BoraMa, et, si tout va bien, pour dissiper une certaine confusion autour de ActiveRecord::Base.abstract_class
.
ActiveRecord::Base.abstract_class
remonte au moins Rails 3.2.0 ( http://api.rubyonrails.org/v3.2.0/classes/ActiveRecord/Inheritance/ClassMethods.html) ), qui a été rendu public le 20 janvier 2012.
Rails 4.0.0 a amélioré la documentation: http://api.rubyonrails.org/v4.0.0/classes/ActiveRecord/Inheritance/ClassMethods.html
Donc, pour tous ceux qui pensent que ApplicationRecord
est radicalement nouveau, ce n'est pas le cas. C'est une amélioration, pas un changement radical. Rien n'a été ajouté à ActiveRecord::Base
pour que cela fonctionne.
J'ai fait la même chose sur un projet Rails 4.2.6 car les modèles utilisaient des UUID pour les identifiants au lieu d’entiers, ce qui nécessitait de modifier le paramètre par défaut ORDER BY
. Ainsi, au lieu d’utiliser un copier-coller ou un problème, j’ai opté pour l’héritage en utilisant une classe UuidModel
et self.abstract_class = true
.