class_eval 和公开课

问题描述 投票:0回答:3

我正在使用 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

ruby spree
3个回答
6
投票

Benjamin,如果现有类不存在或未加载,重新打开类不会通知您(但

class_eval
会引发错误)。

但是如果你有测试覆盖率,我想重新上课应该是安全的?

请参阅 https://stackoverflow.com/a/900508/474597 了解更多详细说明。


0
投票

如果没有 class_eval 就无法更改类。 只要尝试重写一种方法,所有其他方法都会消失。使用 class_eval 你可以避免它。这就是红宝石的方式。


0
投票

还有另一种方法可以解决这个问题,在 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
© www.soinside.com 2019 - 2024. All rights reserved.