我正在使用 Spree,Spree 有一个名为
Order
的类,如下所示:
module Spree
class Order
# class definition.
end
end
在我自己的应用程序中,我一直在自定义
Order
,如下所示:
Spree::Order.class_eval do
# customisations
end
我的问题是,我可以简单地这样做吗:
module Spree
class Order
# My own customisations.
end
end
这有什么缺点吗?本质上,我想避免使用
class_eval
。
Benjamin,如果现有类不存在或未加载,重新打开类不会通知您(但
class_eval
会引发错误)。
但是如果你有测试覆盖率,我想重新上课应该是安全的?
请参阅 https://stackoverflow.com/a/900508/474597 了解更多详细说明。
如果没有 class_eval 就无法更改类。 只要尝试重写一种方法,所有其他方法都会消失。使用 class_eval 你可以避免它。这就是红宝石的方式。
还有另一种方法可以解决这个问题,在 Spree 的情况下效果很好。我想我应该把这个答案留给其他与 Spree 一起工作的人。
您可以使用
prepend
来“安排”在 Spree 最终加载时重新打开课程。
module Spree
# Decorates Spree::Order
module OrderDecorator
CANCELLATION_STATES = %w[canceled pre_canceled].freeze
def self.prepended(base)
base.belongs_to :delivery, class_name: 'Delivery', foreign_key: 'delivery_id', optional: true
base.scope :deliverable, lambda { }
end
end
end
Spree::Order.prepend Spree::OrderDecorator
如果你的装饰器模块获得太多方法,你可以而且应该使用多个方法并控制前置顺序。
Spree::Order.prepend Spree::OrderDecorator
Spree::Order.prepend Admin::SpreeOrderAdminable