Qqw*_*qwy 11 ruby inheritance activerecord callback ruby-on-rails-4
我正在阅读The Rails 4的方式(由Obie Fernandez撰写),一本关于Rails的着名书籍,从我到目前为止所阅读的内容,我强烈推荐它.
但是,有一个示例部分9.2.7.1:一个类中的多个回调方法让我困惑:
忍受我,为了让每个人都明白这个问题,我已经复制了本书在这个问题中描述的步骤.
关于活动记录的回调(本节谈判before_create
,before_update
等等),并且它可以创建一个能处理多种回调为你的类.列出的代码如下:
class Auditor
def initialize(audit_log)
@audit_log = audit_log
end
def after_create(model)
@audit_log.created(model.inspect)
end
def after_update(model)
@audit_log.updated(model.inspect)
end
def after_destroy(model)
@audit_log.destroyed(model.inspect)
end
end
Run Code Online (Sandbox Code Playgroud)
该书说,要将此审核日志记录添加到Active Record类,您将执行以下操作:
class Account < ActiveRecord::Base
after_create Auditor.new(DEFAULT_AUDIT_LOG)
after_update Auditor.new(DEFAULT_AUDIT_LOG)
after_destroy Auditor.new(DEFAULT_AUDIT_LOG)
...
end
Run Code Online (Sandbox Code Playgroud)
然后,本书指出这段代码非常难看,不得不在三行上添加三个审核员,而且它不干.然后继续告诉我们,要解决这个问题,我们应该将一个acts_as_audited
方法修补到Active Record::Base
对象中,如下所示:
(这本书建议把这个文件放进去/lib/core_ext/active_record_base.rb
)
class ActiveRecord::Base
def self.acts_as_audited(audit_log=DEFAULT_AUDIT_LOG)
auditor = Auditor.new(audit_log)
after_create auditor
after_update auditor
after_destroy auditor
end
end
Run Code Online (Sandbox Code Playgroud)
这使您可以编写Account Model类,如下所示:
class Account < ActiveRecord::Base
acts_as_audited
...
end
Run Code Online (Sandbox Code Playgroud)
在阅读本书之前,我已经做了类似的事情,为多个Active Record模型添加了功能.我使用的技术是创建一个模块.为了坚持这个例子,我所做的与以下内容类似:
(我会把这个文件放在里面/app/models/auditable.rb
)
module Auditable
def self.included(base)
@audit_log = base.audit_log || DEFAULT_AUDIT_LOG #The base class can override it if wanted, by specifying a self.audit_log before including this module
base.after_create audit_after_create
base.after_update audit_after_update
base.after_destroy audit_after_destroy
end
def audit_after_create
@audit_log.created(self.inspect)
end
def audit_after_update
@audit_log.updated(self.inspect)
end
def audit_after_destroy
@audit_log.destroyed(self.inspect)
end
end
Run Code Online (Sandbox Code Playgroud)
请注意,此文件都替换Auditor
了猴子修补ActiveRecord::Base
方法.Account
然后这个类看起来像:
class Account < ActiveRecord::Base
include Auditable
...
end
Run Code Online (Sandbox Code Playgroud)
现在你已经阅读了这本书的方式,以及我过去的方式.我的问题:从长远来看哪个版本更具可持续性?我意识到这是一个有点自以为是的问题,就像关于Rails的一切一样,但为了让它负责,我基本上想知道:
ActiveRecord::Base
直接修补猴子,而不是创造和包括Module
?我会选择这个模块有几个原因。
很明显; 也就是说,我可以很快找到定义这个行为的代码。我acts_as_*
不知道它是否来自某些 gem、库代码或在此类中定义。它可能会被覆盖或搭载在调用堆栈中。
它是便携式的。它使用定义回调的库中通常定义的方法调用。您可以想象在非活动记录对象中分发和使用该库。
它避免了在静态级别添加不必要的代码。我喜欢管理更少的代码(需要破坏的代码更少)。我喜欢使用 Ruby 的优点,而不需要做太多事情来强迫它比现在“更好”。
在猴子补丁设置中,您将代码绑定到可能消失的类或模块,并且在某些情况下,它会默默地失败,直到您的类无法调用acts_as_*
.
可移植性论证的失败之一是测试论证。在这种情况下,我想说,您可以编写代码来防止可移植性,或者尽早失败,并发出智能警告,说明在可移植性使用时什么会起作用,什么不会起作用。
归档时间: |
|
查看次数: |
1591 次 |
最近记录: |