Skip to content

Commit

Permalink
Defer Active Storage service configuration until use
Browse files Browse the repository at this point in the history
  • Loading branch information
georgeclaghorn committed Nov 8, 2019
1 parent 986d3bf commit 709cee9
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 47 deletions.
7 changes: 4 additions & 3 deletions activestorage/app/models/active_storage/blob.rb
Expand Up @@ -32,6 +32,7 @@ class ActiveStorage::Blob < ActiveRecord::Base
has_secure_token :key, length: MINIMUM_TOKEN_LENGTH
store :metadata, accessors: [ :analyzed, :identified ], coder: ActiveRecord::Coders::JSON

class_attribute :services, default: {}
class_attribute :service

has_many :attachments
Expand All @@ -49,8 +50,8 @@ class ActiveStorage::Blob < ActiveRecord::Base
validates :service_name, presence: true

validate do
if service_name_changed? && service_name
ActiveStorage::ServiceRegistry.fetch(service_name) do
if service_name_changed? && service_name.present?
services.fetch(service_name) do
errors.add(:service_name, :invalid)
end
end
Expand Down Expand Up @@ -266,7 +267,7 @@ def purge_later

# Returns an instance of service, which can be configured globally or per attachment
def service
ActiveStorage::ServiceRegistry.fetch(service_name)
services.fetch(service_name)
end

private
Expand Down
1 change: 0 additions & 1 deletion activestorage/lib/active_storage.rb
Expand Up @@ -38,7 +38,6 @@ module ActiveStorage

autoload :Attached
autoload :Service
autoload :ServiceRegistry
autoload :Previewer
autoload :Analyzer

Expand Down
8 changes: 4 additions & 4 deletions activestorage/lib/active_storage/attached/model.rb
Expand Up @@ -165,10 +165,10 @@ def purge_later

private
def validate_service_configuration(association_name, service)
return unless service

ServiceRegistry.fetch(service) do
raise ArgumentError, "Cannot configure service :#{service} for #{name}##{association_name}"
if service.present?
ActiveStorage::Blob.services.fetch(service) do
raise ArgumentError, "Cannot configure service :#{service} for #{name}##{association_name}"
end
end
end
end
Expand Down
23 changes: 20 additions & 3 deletions activestorage/lib/active_storage/engine.rb
Expand Up @@ -14,6 +14,8 @@
require "active_storage/analyzer/image_analyzer"
require "active_storage/analyzer/video_analyzer"

require "active_storage/service/registry"

require "active_storage/reflection"

module ActiveStorage
Expand Down Expand Up @@ -101,10 +103,25 @@ class Engine < Rails::Engine # :nodoc:

initializer "active_storage.services" do
ActiveSupport.on_load(:active_storage_blob) do
if config_choice = Rails.configuration.active_storage.service
ActiveStorage::Blob.service = ActiveStorage::ServiceRegistry.fetch(config_choice) do
raise ArgumentError, "Cannot load `Rails.application.config.active_storage.service`:\n#{config_choice}"
configs = Rails.configuration.active_storage.service_configurations ||=
begin
config_file = Pathname.new(Rails.root.join("config/storage.yml"))
raise("Couldn't find Active Storage configuration in #{config_file}") unless config_file.exist?

require "yaml"
require "erb"

YAML.load(ERB.new(config_file.read).result) || {}
rescue Psych::SyntaxError => e
raise "YAML syntax error occurred while parsing #{config_file}. " \
"Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
"Error: #{e.message}"
end

ActiveStorage::Blob.services = ActiveStorage::Service::Registry.new(configs)

if config_choice = Rails.configuration.active_storage.service
ActiveStorage::Blob.service = ActiveStorage::Blob.services.fetch(config_choice)
end
end
end
Expand Down
32 changes: 32 additions & 0 deletions activestorage/lib/active_storage/service/registry.rb
@@ -0,0 +1,32 @@
# frozen_string_literal: true

module ActiveStorage
class Service::Registry #:nodoc:
def initialize(configurations)
@configurations = configurations.deep_symbolize_keys
@services = {}
end

def fetch(name)
services.fetch(name.to_sym) do |key|
if configurations.include?(key)
services[key] = configurator.build(key)
else
if block_given?
yield key
else
raise KeyError, "Missing configuration for the #{key} Active Storage service. " \
"Configurations available for the #{configurations.keys.to_sentence} services."
end
end
end
end

private
attr_reader :configurations, :services

def configurator
@configurator ||= ActiveStorage::Service::Configurator.new(configurations)
end
end
end
34 changes: 0 additions & 34 deletions activestorage/lib/active_storage/service_registry.rb

This file was deleted.

3 changes: 1 addition & 2 deletions activestorage/test/test_helper.rb
Expand Up @@ -103,9 +103,8 @@ def fixture_file_upload(filename)
end

def with_service(service_name)
service = ActiveStorage::ServiceRegistry.fetch(service_name)
previous_service = ActiveStorage::Blob.service
ActiveStorage::Blob.service = service
ActiveStorage::Blob.service = ActiveStorage::Blob.services.fetch(service_name)

yield
ensure
Expand Down

0 comments on commit 709cee9

Please sign in to comment.