为什么Rails 5使用ApplicationRecord而不是ActiveRecord :: Base?

Hie*_*ham 50 ruby-on-rails ruby-on-rails-4 ruby-on-rails-5

我们知道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
Run Code Online (Sandbox Code Playgroud)

所以现在每个模型都会附上行为MyFeatures.但我们也可以在Rails 4中实现这一点:

ActiveRecord::Base.include(MyFeatures)
Run Code Online (Sandbox Code Playgroud)

那么使用的好处是什么ApplicationRecord,您认为有必要添加ApplicationRecord吗?

Bor*_*aMa 66

虽然在基本的Rails应用程序中看起来可能相同,但是一旦开始使用rails引擎,插件/ gems或直接方法,实际上会有一个重要的区别ActiveRecord::Base.

  • ActiveRecord::Base.include(MyFeatures)将特征直接混合到其中ActiveRecord::Base并且它永远存在于那里以供以后的所有使用ActiveRecord::Base(它不能"未混合")并且ActiveRecord::Base在包含之后的任何代码中都无法获得原始内容.如果某些混合功能更改了默认的ActiveRecord行为,或者例如两个引擎/ gems尝试包含同名方法,则很容易导致问题.

  • 另一方面,该ApplicationRecord方法使得特征仅出现在从其继承的类(模型),其他类,以及直接使用ActiveRecord::Base保持原始,由模块特征整理.

当使用引擎或轨道插件时,这一点尤其重要,因为它允许它们将自己的模型逻辑与主应用程序的模型逻辑分开,这在以前是不可能的ApplicationRecord.

所有这一切也在这篇博文github评论中得到了很好的描述.

  • 扩展`ActiveRecord :: Base`的每一个宝石现在都会被打破吗?如果是这样,那就是创造了大量的维护和技术债务. (3认同)

Jor*_*ell 9

这是为了扩展@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),它于2012年1月20日发布.

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.所以,我没有使用复制粘贴或关注,而是使用UuidModel类和继承继承self.abstract_class = true.