Spree::AppConfigurationclass has a list of all the service object classes that can be natively customized. Look for through the source code of that class and see if there's an option that resembles what you need to do. If yes, bingo!
Spree::OrderMergerclass to understand what public API Solidus expects us to implement in our custom version:
#initialize, which accepts an order.
#merge!, which accepts another order to merge with the first one and (optionally) the current user.
Spree::Order#finalize!method to do it, but what if the implementation changes and the finalization logic is moved somewhere else? With the event bus, you can ask Solidus to run your custom logic whenever an order is finalized, without having to know about the platform's internals.
OrderNotificationSubscribermodule that looks like this:
Spree::Productalready has an
#available?method to control a product's visibility. This is the original implementation:
Module#prepend. If you're not familiar with it,
#prependis a method that allows us to insert a module at the beginning of another module's ancestors chain. Think of it as taking a module A and placing it "in front" of another module B: when you call a method on module B, Ruby will first hit module A and then continue down the chain of ancestors.
Spree::Product#available?method by writing a module that will be prepended to
Spree::Product. In the Solidus ecosystem, we call such modules overrides. Overrides are usually named in a descriptive way, that expresses how the override extends the original class.
#available?implementation, but we can also call the original implementation with
super. This allows you to decide whether you want to extend the original method or completely override it.