Skip to content

Commit

Permalink
Support code reloading when configuring static preferences sources
Browse files Browse the repository at this point in the history
This is how we usually recommend configuring sources for static
preferences [1]:

```ruby
Spree.config do |config|
  config.static_model_preferences.add(
    AmazingStore::AmazingPaymentMethod,
    'amazing_payment_method_credentials',
    credentials: ENV['AMAZING_PAYMENT_METHOD_CREDENTIALS'],
    server: Rails.env.production? ? 'production' : 'test',
    test_mode: !Rails.env.production?
  )
end
```

However, it's no longer possible to directly reference an autoloadable
class from an initializer [2].

In this case, we can't change the `#add` method to take the class name
instead. The reason is that it ends up invoking a sanitization check on
the given preferences against the defined preferences, and that, of
course, needs access to the actual class [3].

Therefore, it's better to start recommending nesting the configuration
within a `.to_prepare` block, as they run every time the code is
reloaded [4]:

```ruby
Rails.application.config.to_prepare do
  Spree::Config.static_model_preferences.add(
    AmazingStore::AmazingPaymentMethod,
    'amazing_payment_method_credentials',
    credentials: ENV['AMAZING_PAYMENT_METHOD_CREDENTIALS'],
    server: Rails.env.production? ? 'production' : 'test',
    test_mode: !Rails.env.production?
  )
end
```

However, that means running the `#add` method multiple times, so we need
to change it to replace the definition instead of raising an error.

[1] - https://github.com/solidusio/solidus_stripe/blob/3fab36511a9d02ebd64d03571704ac5a9031b63b/README.md#usage
[2] - https://guides.rubyonrails.org/autoloading_and_reloading_constants.html#autoload-on-boot-and-on-each-reload
[3] - https://github.com/solidusio/solidus/blob/df51df62fa9b829216958b21b20514b7a3d87b30/core/lib/spree/preferences/static_model_preferences.rb#L13
[4] - https://guides.rubyonrails.org/configuring.html#initialization-events

Closes solidusio#4070 & solidusio#4040
  • Loading branch information
waiting-for-dev committed Jul 13, 2022
1 parent df51df6 commit 77b6b36
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 2 deletions.
2 changes: 0 additions & 2 deletions core/lib/spree/preferences/static_model_preferences.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ def initialize
end

def add(klass, name, preferences)
# We use class name instead of class to allow reloading in dev
raise "Static model preference '#{name}' on #{klass} is already defined" if @store[klass.to_s][name]
@store[klass.to_s][name] = Definition.new(klass, preferences)
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ module Spree
expect(definitions).to have_key('my_definition')
end

it "can replace preferences" do
subject.add(preference_class, 'my_definition', { color: "red" })

subject.add(preference_class, 'my_definition', { color: "blue" })

expect(definitions['my_definition'].fetch(:color)).to eq("blue")
end

it "errors assigning invalid preferences" do
expect {
subject.add(preference_class, 'my_definition', { ice_cream: 'chocolate' })
Expand Down

0 comments on commit 77b6b36

Please sign in to comment.