Почему 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
?
Ответы
Ответ 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
.