为啥 Rails 5 使用 ApplicationRecord 而不是 ActiveRecord::Base?
Posted
技术标签:
【中文标题】为啥 Rails 5 使用 ApplicationRecord 而不是 ActiveRecord::Base?【英文标题】:Why Rails 5 uses ApplicationRecord instead of ActiveRecord::Base?为什么 Rails 5 使用 ApplicationRecord 而不是 ActiveRecord::Base? 【发布时间】:2016-09-18 11:26:36 【问题描述】:我们知道 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
的 Rails 引擎、插件/gem 或直接方法时,实际上会有一个重要的区别。
ActiveRecord::Base.include(MyFeatures)
将特征直接混合到ActiveRecord::Base
中,并且它永远存在于ActiveRecord::Base
的所有以后使用中(它不能“未混合”)并且没有办法获得原始@ 987654327@ 不再包含在任何代码中。如果某些混合功能更改了默认的 ActiveRecord 行为,或者例如两个引擎/gem 试图包含同名方法。
另一方面,ApplicationRecord
方法使特性仅适用于继承自它的类(模型)、其他类,以及直接使用 @987654329 @保持原始状态,不受模块功能的影响。
这在使用引擎或 Rails 插件时尤其重要,因为它允许它们将自己的模型逻辑与主应用程序的模型逻辑分开,这在 ApplicationRecord
之前是不可能的。
this blog post 和 this github comment 也很好地描述了所有这些。
【讨论】:
每个扩展ActiveRecord::Base
的 gem 现在会因此被破坏吗?如果是这样,那将产生大量的维护和技术债务。
感谢 BoraMa 提供如此详细的回答并提及博客链接。请务必访问博客链接,因为它通过示例非常清楚地解释了。作为 Rails 的新手,它提供了非常丰富的信息。【参考方案2】:
这是对@BoraMa 的回答的扩展,并希望能消除围绕ActiveRecord::Base.abstract_class
的一些困惑。
ActiveRecord::Base.abstract_class
至少可以追溯到 2012 年 1 月 20 日发布的 Rails 3.2.0 (http://api.rubyonrails.org/v3.2.0/classes/ActiveRecord/Inheritance/ClassMethods.html)。
Rails 4.0.0 改进了文档:http://api.rubyonrails.org/v4.0.0/classes/ActiveRecord/Inheritance/ClassMethods.html
所以,对于所有认为ApplicationRecord
是全新的人来说,事实并非如此。这是一种改进,而不是突破性的变化。没有任何内容添加到 ActiveRecord::Base
来完成这项工作。
我在 Rails 4.2.6 项目上做了同样的事情,因为模型使用 UUID 来表示 id 而不是整数,这需要更改默认的 ORDER BY
。因此,我没有使用复制粘贴或关注点,而是使用UuidModel
类和self.abstract_class = true
进行继承。
【讨论】:
我记得 Rails 2.x 中的abstract_class
。以上是关于为啥 Rails 5 使用 ApplicationRecord 而不是 ActiveRecord::Base?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Rails 5 使用 ApplicationRecord 而不是 ActiveRecord::Base?
stylesheet_pack_tag 在带有 webpacker gem 的 rails 5.1 中找不到 app/javascript/src/application.css