Module: Spree::DependenciesHelper
- Included in:
- Core::Dependencies
- Defined in:
- lib/spree/core/dependencies_helper.rb
Constant Summary collapse
- INTERNAL_CALLER_PATTERNS =
Patterns to skip when finding the actual caller (internal routing code)
[ %r{lib/spree/core\.rb.*method_missing}, %r{lib/spree/api\.rb.*method_missing} ].freeze
Class Method Summary collapse
Instance Method Summary collapse
-
#current_values ⇒ Object
Returns array of all dependencies with current values and metadata.
- #initialize ⇒ Object
-
#overridden?(name) ⇒ Boolean
Check if a specific dependency has been overridden.
-
#override_info(name) ⇒ Object
Get override info for a specific dependency.
-
#overrides ⇒ Object
Returns hash of all overridden dependencies with metadata.
-
#validate! ⇒ Object
Validate all dependencies can be resolved to classes Raises Spree::DependencyError if any dependency is invalid.
Class Method Details
.included(base) ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/spree/core/dependencies_helper.rb', line 11 def self.included(base) injection_points = base::INJECTION_POINTS_WITH_DEFAULTS.keys.freeze base.const_set(:INJECTION_POINTS, injection_points) injection_points.each do |point| # Original getter - returns raw value (string, class, or proc result) # BACKWARDS COMPATIBLE: Spree::Dependencies.foo.constantize still works base.attr_reader(point) # Setter with override tracking # BACKWARDS COMPATIBLE: Spree::Dependencies.foo = "MyClass" still works base.define_method("#{point}=") do |value| @overrides ||= {} @overrides[point] = { value: value, source: find_caller_source, set_at: Time.current } # Clear memoized class when value changes remove_instance_variable("@#{point}_resolved") if instance_variable_defined?("@#{point}_resolved") instance_variable_set("@#{point}", value) end # Returns resolved class with memoization # Usage: Spree::Dependencies.foo_class or Spree.foo base.define_method("#{point}_class") do return instance_variable_get("@#{point}_resolved") if instance_variable_defined?("@#{point}_resolved") value = send(point) resolved = case value when String then value.constantize when Proc then value.call.then { |v| v.is_a?(String) ? v.constantize : v } else value end instance_variable_set("@#{point}_resolved", resolved) resolved end end end |
Instance Method Details
#current_values ⇒ Object
Returns array of all dependencies with current values and metadata
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/spree/core/dependencies_helper.rb', line 71 def current_values self.class::INJECTION_POINTS.map do |point| default = self.class::INJECTION_POINTS_WITH_DEFAULTS[point] default_val = default.respond_to?(:call) ? default.call : default current = send(point) { name: point, current: current, default: default_val, # Use overridden? to check if setter was called, not value comparison # Value comparison fails for proc-based defaults that reference other dependencies overridden: overridden?(point), override_info: overrides[point] } end end |
#initialize ⇒ Object
51 52 53 |
# File 'lib/spree/core/dependencies_helper.rb', line 51 def initialize set_default_values end |
#overridden?(name) ⇒ Boolean
Check if a specific dependency has been overridden
61 62 63 |
# File 'lib/spree/core/dependencies_helper.rb', line 61 def overridden?(name) overrides.key?(name.to_sym) end |
#override_info(name) ⇒ Object
Get override info for a specific dependency
66 67 68 |
# File 'lib/spree/core/dependencies_helper.rb', line 66 def override_info(name) overrides[name.to_sym] end |
#overrides ⇒ Object
Returns hash of all overridden dependencies with metadata
56 57 58 |
# File 'lib/spree/core/dependencies_helper.rb', line 56 def overrides @overrides || {} end |
#validate! ⇒ Object
Validate all dependencies can be resolved to classes Raises Spree::DependencyError if any dependency is invalid
91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/spree/core/dependencies_helper.rb', line 91 def validate! errors = [] self.class::INJECTION_POINTS.each do |point| send("#{point}_class") rescue NameError => e errors << { name: point, value: send(point), error: e. } end raise Spree::DependencyError, "Invalid dependencies: #{errors.map { |e| e[:name] }.join(', ')}" if errors.any? true end |