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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 00:25:13  来源:igfitidea点击:

Why Rails 5 uses ApplicationRecord instead of ActiveRecord::Base?

ruby-on-railsruby-on-rails-4ruby-on-rails-5

提问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 into ActiveRecord::Baseand it is present there forever for all later uses of ActiveRecord::Base(it cannot be "unmixed") and there is no way to get the original ActiveRecord::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 of ActiveRecord::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.