web-dev-qa-db-fra.com

Pourquoi Rails 5 utilise ApplicationRecord au lieu de ActiveRecord :: Base?

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?

48
Hieu Pham

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 .

64
BoraMa

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.

9
Jordan Pickwell