Skip to content

Commit

Permalink
Dynamically (re)load Solidus core subscribers
Browse files Browse the repository at this point in the history
Until now, adding subscribers to Spree::Event.subscribers was
developers' responsibility.

This commit aims at automating the task by making Rails load
subscriber files located in standard paths both in Solidus
core and in the store app during the Rails initialization
processs.
When each file is required, it's now also added to the
`Spree::Event.subscribers` list.
  • Loading branch information
spaghetticode committed Mar 31, 2020
1 parent 596bdc7 commit 5153e60
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 3 deletions.
1 change: 1 addition & 0 deletions core/lib/spree/core/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class Engine < ::Rails::Engine
# Setup Event Subscribers
initializer 'spree.core.initialize_subscribers' do |app|
app.reloader.to_prepare do
Spree::Event.require_subscriber_files
Spree::Event.subscribers.each(&:subscribe!)
end

Expand Down
18 changes: 18 additions & 0 deletions core/lib/spree/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,24 @@ def fire(event_name, opts = {})
end
end

# Loads all Solidus' core and application's event subscribers files.
#
# Files must be placed under the directory `app/subscribers` and their name
# must end with `_subscriber.rb`.
#
# Loading the files has the side effect of adding their module to the list
# in Spree::Event.subscribers.
def require_subscriber_files
pattern = "app/subscribers/**/*_subscriber.rb"
# Load Solidus subscribers
# rubocop:disable Rails/DynamicFindBy
solidus_core_dir = Gem::Specification.find_by_name('solidus_core').gem_dir
# rubocop:enable Rails/DynamicFindBy
Dir.glob(File.join(solidus_core_dir, pattern)) { |c| require_dependency(c.to_s) }
# Load application subscribers
Rails.root.glob(pattern) { |c| require_dependency(c.to_s) }
end

# Subscribe to an event with the given name. The provided block is executed
# every time the subscribed event is fired.
#
Expand Down
4 changes: 1 addition & 3 deletions core/lib/spree/event/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ module Spree
module Event
class Configuration
def subscribers
@subscribers ||= ::Spree::Core::ClassConstantizer::Set.new.tap do |set|
set << 'Spree::MailerSubscriber'
end
@subscribers ||= ::Spree::Core::ClassConstantizer::Set.new
end

attr_writer :adapter, :suffix
Expand Down
2 changes: 2 additions & 0 deletions core/lib/spree/event/subscriber.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ def self.included(base)

base.mattr_accessor :event_actions
base.event_actions = {}

Spree::Event.subscribers << base.name
end

# Declares a method name in the including module that can be subscribed/unsubscribed
Expand Down
24 changes: 24 additions & 0 deletions core/spec/lib/spree/event_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@
allow(subscriber_name).to receive(:to_s).and_return(subscriber_name)
end

after { described_class.subscribers.clear }

it 'accepts the names of constants' do
Spree::Config.events.subscribers << subscriber_name

Expand All @@ -133,4 +135,26 @@
expect(described_class.subscribers.to_a).to eq([subscriber])
end
end

describe '.require_subscriber_files' do
let(:susbcribers_dir) { Rails.root.join("app", "subscribers", "spree") }

def create_foo_subscriber_file
FileUtils.mkdir_p(susbcribers_dir)
File.open File.join(susbcribers_dir, 'foo_subscriber.rb'), 'w' do |f|
f.puts "module Spree::FooSubscriber; include Spree::Event::Subscriber; end"
end
end

before { create_foo_subscriber_file }
after { FileUtils.rm_rf(susbcribers_dir) }

it 'requires subscriber files and loads them into Spree::Event.subscribers' do
expect do
described_class.require_subscriber_files
end.to change { described_class.subscribers.count }.by 1

expect(described_class.subscribers).to include Spree::FooSubscriber
end
end
end

0 comments on commit 5153e60

Please sign in to comment.