Ruby-on-rails 为什么 Rails 5 使用 ApplicationRecord 而不是 ActiveRecord::Base?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37359527/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why Rails 5 uses ApplicationRecord instead of ActiveRecord::Base?
提问by Hieu Pham
We know that Rails 5 added ApplicationRecordas an abstract class which was inherited by our models (ActiveRecord).
我们知道 Rails 5ApplicationRecord作为抽象类添加到我们的模型 (ActiveRecord) 中继承。
But basically, I think every technical requirement we do with ApplicationRecord, we can also do with ActiveRecord::Base. For instance:
但基本上,我认为我们用 ApplicationRecord 做的每一个技术要求,我们也可以用ActiveRecord::Base. 例如:
module MyFeatures
def do_something
puts "Doing something"
end
end
class ApplicationRecord < ActiveRecord::Base
include MyFeatures
self.abstract_class = true
end
So now every model will be attached the behaviors of MyFeatures. But we can also achieve this in Rails 4:
所以现在每个模型都将附加MyFeatures. 但我们也可以在 Rails 4 中实现这一点:
ActiveRecord::Base.include(MyFeatures)
So what is the benefit of using ApplicationRecord, do you think it is necessary to add ApplicationRecord?
那么使用有什么好处ApplicationRecord,你觉得有必要加ApplicationRecord吗?
回答by BoraMa
While it may seem the same in basic Rails applications, there actually is an important difference once you begin to use rails engines, plugins / gems or direct methods from ActiveRecord::Base.
虽然在基本的 Rails 应用程序中看起来是一样的,但一旦你开始使用 Rails 引擎、插件/gems 或来自ActiveRecord::Base.
ActiveRecord::Base.include(MyFeatures)mixes in the features directly intoActiveRecord::Baseand it is present there forever for all later uses ofActiveRecord::Base(it cannot be "unmixed") and there is no way to get the originalActiveRecord::Baseanymore in any code after the include. This can easily lead to problems if some of the mixed in feature changed the default ActiveRecord behavior or if e.g. two engines / gems tried to include same-named methods.On the other hand, the
ApplicationRecordapproach makes the features present only for the classes (models) that inherit from it, other classes, as well as direct use ofActiveRecord::Basestay pristine, uncluttered by the module features.
ActiveRecord::Base.include(MyFeatures)将功能直接混合到其中,ActiveRecord::Base并且它永远存在于所有以后的使用中ActiveRecord::Base(它不能“未混合”)并且在包含之后无法ActiveRecord::Base再在任何代码中获取原始内容。如果某些混合特性改变了默认的 ActiveRecord 行为,或者如果两个引擎 / gems 试图包含同名方法,这很容易导致问题。另一方面,该
ApplicationRecord方法使特性仅存在于继承自它的类(模型)、其他类以及直接使用ActiveRecord::Base保持原始状态,不受模块特性的影响。
This is especially important when engines or rails plugins are used as it allows them to separate their own model logic from the main application's model logic which was not possible before ApplicationRecord.
这在使用引擎或 rails 插件时尤其重要,因为它允许它们将自己的模型逻辑与主应用程序的模型逻辑分开,这在以前是不可能的ApplicationRecord。
All of this is also nicely described in this blog postand this github comment.
所有这一切也在这篇博文和这篇 github 评论中得到了很好的描述。
回答by Jordan Pickwell
This is to expand on @BoraMa's answer, and to, hopefully, clear up some confusion around ActiveRecord::Base.abstract_class.
这是为了扩展@BoraMa 的回答,并希望能消除一些关于ActiveRecord::Base.abstract_class.
ActiveRecord::Base.abstract_classgoes back to at least Rails 3.2.0 (http://api.rubyonrails.org/v3.2.0/classes/ActiveRecord/Inheritance/ClassMethods.html), which was released on January 20, 2012.
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 improved the documentation: http://api.rubyonrails.org/v4.0.0/classes/ActiveRecord/Inheritance/ClassMethods.html
Rails 4.0.0 改进了文档:http: //api.rubyonrails.org/v4.0.0/classes/ActiveRecord/Inheritance/ClassMethods.html
So, to everyone who thinks ApplicationRecordis radically new, it's not. It is an improvement, not a breaking change. Nothing was added to ActiveRecord::Baseto make this work.
因此,对于所有认为ApplicationRecord是全新事物的人来说,事实并非如此。这是一种改进,而不是破坏性的改变。没有添加任何东西来ActiveRecord::Base完成这项工作。
I did the same thing on a Rails 4.2.6 project because the models used UUIDs for ids instead of integers, and this required a change to the default ORDER BY. So, instead of using copy-paste or a concern, I went with inheritance using a UuidModelclass and self.abstract_class = true.
我在 Rails 4.2.6 项目上做了同样的事情,因为模型使用 UUID 作为 ids 而不是整数,这需要更改默认的ORDER BY. 因此,我没有使用复制粘贴或关注,而是使用UuidModel类和self.abstract_class = true.

