Reputation: 9691
I am using Spree, and Spree has a class called Order
that looks like:
module Spree
class Order
# class definition.
end
end
In my own app, I have been customising Order
like so:
Spree::Order.class_eval do
# customisations
end
My question is, can I simply just do this:
module Spree
class Order
# My own customisations.
end
end
Any downsides to this? Essentially, I want to avoid using class_eval
.
Upvotes: 13
Views: 1530
Reputation: 7324
There is another way to solve this problem, which works quite well in the case of Spree. I thought I'd leave this answer for others working with Spree.
You can use prepend
in order to 'schedule' the class reopening at whatever time that Spree is finally loaded.
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
If your decorator modules gets too many methods, you can and should use multiple and control the prepend order.
Spree::Order.prepend Spree::OrderDecorator
Spree::Order.prepend Admin::SpreeOrderAdminable
Upvotes: 0
Reputation: 393
Benjamin, reopen class will not inform you (but class_eval
will raise error) if the existing class does not exist or not loaded.
But if you have test coverage, reopen class should be safe I guess?
See https://stackoverflow.com/a/900508/474597 for more detailed explanation.
Upvotes: 6
Reputation: 2280
you cant alter the class without class_eval. just try to override one method, and all other methods are gone. with class_eval you avoid it. thats the ruby way.
Upvotes: -1