Подтвердить что ты не робот

Почему Rails 5 использует ApplicationRecord вместо ActiveRecord:: Base?

Мы знаем, что Rails 5 добавил ApplicationRecord как абстрактный класс, который был унаследован нашими моделями (ActiveRecord).

Но в основном, я думаю, что каждое техническое требование, которое мы делаем с ApplicationRecord, мы также можем делать с ActiveRecord::Base. Например:

module MyFeatures
  def do_something
    puts "Doing something"
  end
end

class ApplicationRecord < ActiveRecord::Base
  include MyFeatures
  self.abstract_class = true
end

Итак, теперь каждая модель будет привязана к поведению MyFeatures. Но мы также можем достичь этого в Rails 4:

ActiveRecord::Base.include(MyFeatures)

Итак, в чем преимущество использования ApplicationRecord, как вы думаете, нужно добавить ApplicationRecord?

4b9b3361

Ответ 1

Хотя в основных приложениях Rails это может показаться одинаковым, на самом деле существует важная разница, как только вы начнете использовать движки рельсов, плагины/драгоценные камни или прямые методы из ActiveRecord::Base.

  • ActiveRecord::Base.include(MyFeatures) смешивается в функциях непосредственно в ActiveRecord::Base и присутствует там навсегда для всех последующих использования ActiveRecord::Base (он не может быть "несмешанным" ), и нет способа получить оригинал ActiveRecord::Base больше в любом коде после включения. Это может легко привести к проблемам, если некоторые из смешанных функций изменили поведение ActiveRecord по умолчанию или, например, два двигателя/драгоценные камни пытались включить однотипные методы.

  • С другой стороны, подход ApplicationRecord делает присутствующие функции только для классов (моделей), которые наследуют от него, других классов, а также прямого использования ActiveRecord::Base оставайтесь чистыми, незагроможденными функциями модуля.

Это особенно важно, когда используются модули плагинов или плагинов, поскольку он позволяет им отделять собственную логику модели от основной логики модели приложения, которая была невозможна до ApplicationRecord.

Все это также хорошо описано в этом сообщении в блоге и этот комментарий github.

Ответ 2

Это расширение для ответа @BoraMa и, надеюсь, устранить некоторую путаницу вокруг ActiveRecord::Base.abstract_class.

ActiveRecord::Base.abstract_class восходит по крайней мере к Rails 3.2.0 (http://api.rubyonrails.org/v3.2.0/classes/ActiveRecord/Inheritance/ClassMethods.html), который был выпущен 20 января 2012 года.

Rails 4.0.0 улучшил документацию: http://api.rubyonrails.org/v4.0.0/classes/ActiveRecord/Inheritance/ClassMethods.html

Итак, всем, кто считает, что ApplicationRecord радикально новый, это не так. Это улучшение, а не резкое изменение. Ничего не было добавлено в ActiveRecord::Base, чтобы сделать эту работу.

Я сделал то же самое в проекте Rails 4.2.6, потому что модели использовали UUID для идентификаторов вместо целых чисел, и для этого потребовалось изменение значения по умолчанию ORDER BY. Таким образом, вместо использования copy-paste или проблемы, я пошел с наследованием, используя класс UuidModel и self.abstract_class = true.