Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow storing static preferences using string class names #4858

Merged
merged 1 commit into from
Jan 23, 2023

Conversation

elia
Copy link
Member

@elia elia commented Jan 16, 2023

Summary

This will make unnecessary to wrap these definitions under .to_prepare blocks.

Additionally the error message for unexpected keys has improved and now lists both all the unexpected keys along with the expected keys, mentioning the name associated to the definition.

The only thing that changed is that it doesn't do so when the configuration is added but rather when it's fetched.

Completes #4070 and addresses the original request of #4040.

Checklist

Check out our PR guidelines for more details.

The following are mandatory for all PRs:

  • I have written a thorough PR description.
  • I have kept my commits small and atomic.
  • I have used clear, explanatory commit messages.

The following are not always needed (cross them out if they are not):

  • I have added automated tests to cover my changes.
  • I have attached screenshots to demo visual changes.
  • I have opened a PR to update the guides.
  • I have updated the README to account for my changes.

@elia elia self-assigned this Jan 16, 2023
@github-actions github-actions bot added the changelog:solidus_core Changes to the solidus_core gem label Jan 16, 2023
@codecov
Copy link

codecov bot commented Jan 16, 2023

Codecov Report

Merging #4858 (8281f98) into master (c6050d7) will increase coverage by 0.00%.
The diff coverage is 100.00%.

@@           Coverage Diff           @@
##           master    #4858   +/-   ##
=======================================
  Coverage   86.23%   86.24%           
=======================================
  Files         578      578           
  Lines       14674    14683    +9     
=======================================
+ Hits        12654    12663    +9     
  Misses       2020     2020           
Impacted Files Coverage Δ
core/lib/spree/core/engine.rb 88.67% <100.00%> (+0.21%) ⬆️
.../lib/spree/preferences/static_model_preferences.rb 100.00% <100.00%> (ø)

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@elia elia marked this pull request as ready for review January 16, 2023 19:31
@elia elia requested a review from a team as a code owner January 16, 2023 19:31
Copy link
Contributor

@waiting-for-dev waiting-for-dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on it, @elia. That's something that needs to be addressed 🙌

However, did you happen to check if we will still render the error message on initialization, or otherwise, will it happen only for affected runtimes? Keeping the first behavior is optimal, as it saves from more headaches on production. If that changes, we could work around that by having one #to_prepare block on our engine doing the sanitization check for all configured preferences.

What do you think?

Comment on lines 33 to 30
@store = Hash.new do |data, klass|
data[klass] = {}
end
@store = {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think it's cleaner to create the Hash with a fresh hash as the default value, for a few reasons:

  • Otherwise, we need to sanitize it every time we access a key, as we're doing now twice in #add & #fetch.
  • Could break something in edge cases where code relies on returning a Hash.
  • In my view, it communicates better as it nails down the data structure we need.

Thoughts?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason I touched this is that while storing prefs for solidus_stripe I noticed that trying a non existing key would add the key to the hash, e.g.:

>> sp = Spree::Preferences::StaticModelPreferences.new
=> #<Spree::Preferences::StaticModelPreferences:0x00000001124dac70 @store={}>
>> sp.for_class("Foo")
=> {}
>> sp
=> 
#<Spree::Preferences::StaticModelPreferences:0x00000001124dac70
 @store={"Foo"=>{}}>          
>> 

I'll change it to a simpler Hash.new { {} } so it behaves this way:

>> h = Hash.new { {} }
=> {}
>> h[:asdf]
=> {}
>> h
=> {}
>> h[:asdf] = 1234
=> 1234
>> h
=> {:asdf=>1234}
>> 

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to walk back on this, my second example wasn't correct, and after all we only need to set the empty hash in #add and fallback to a default in #for_class which is not much.

The whole preferences system could probably be simplified but didn't want to launch into a campaign, and this will at least provide a consistent the experience within initializers.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I see. I never realized that Ruby had this behavior. What about the change in the API (i.e., returning nil instead of Hash? Do you think it's plausible it could break stores? cc @kennyadsl

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say that the whole API a bit sparse and could be streamlined, it also only serves one model inside solidus (although it's probably more across the ecosystem). But I wanted to surgically solve only the problem of not being able to pass strings for class names and finally make it consistent with other parts of the configuration.

There's also probably a case for making some of these APIs to be private and so not susceptible to backward compatibility support.

@elia elia force-pushed the elia/static-model-preferences branch from 9418515 to 521aae9 Compare January 17, 2023 11:38
@elia elia requested a review from waiting-for-dev January 17, 2023 11:38
@waiting-for-dev
Copy link
Contributor

Hey, @elia, it looks nice, but what do you think about:

However, did you happen to check if we will still render the error message on initialization, or otherwise, will it happen only for affected runtimes? Keeping the first behavior is optimal, as it saves from more headaches on production. If that changes, we could work around that by having one #to_prepare block on our engine doing the sanitization check for all configured preferences.

@elia elia force-pushed the elia/static-model-preferences branch from 521aae9 to 55b4df4 Compare January 18, 2023 12:20
@elia
Copy link
Member Author

elia commented Jan 18, 2023

However, did you happen to check if we will still render the error message on initialization, or otherwise, will it happen only for affected runtimes? Keeping the first behavior is optimal, as it saves from more headaches on production. If that changes, we could work around that by having one #to_prepare block on our engine doing the sanitization check for all configured preferences.

What do you think?

@waiting-for-dev sorry I though I addressed that! I updated the PR moving the check to a validate! method that is being run once inside an after_initializer. Since the static preferences are not reloaded I thought it's not strictly necessary to check at every code change.

@elia elia requested review from waiting-for-dev and removed request for waiting-for-dev January 18, 2023 12:22
@elia elia force-pushed the elia/static-model-preferences branch 2 times, most recently from 5280935 to e7835f5 Compare January 19, 2023 16:15
@@ -87,6 +87,7 @@ class Engine < ::Rails::Engine

config.after_initialize do
Spree::Config.check_load_defaults_called('Spree::Config')
Spree::Config.static_model_preferences.validate!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if you set the preference value after the app is initialized? Do you need to call validate! manually as well?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the app is initialized you could change the model configuration (e.g. adding or removing a preference) not the static preference value, but I regarded that as infrequent.

If we want to do it at every request in development we could move it to a to_prepare block, would you prefer that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, they live in memory and we can't change their value at runtime. At least, not easily and it's not an expected usage.

This will make unnecessary to wrap these definitions under `.to_prepare`
blocks.

Additionally the error message for unexpected keys has improved and
now lists both all the unexpected keys along with the expected keys,
mentioning the name associated to the definition.
@elia elia force-pushed the elia/static-model-preferences branch from e7835f5 to 8281f98 Compare January 23, 2023 10:32
Copy link
Contributor

@waiting-for-dev waiting-for-dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

@kennyadsl kennyadsl added the type:enhancement Proposed or newly added feature label Jan 23, 2023
@kennyadsl kennyadsl merged commit 07d570f into master Jan 23, 2023
@kennyadsl kennyadsl deleted the elia/static-model-preferences branch January 23, 2023 13:20
elia added a commit to solidusio/edgeguides that referenced this pull request Jan 23, 2023
waiting-for-dev added a commit to solidusio/edgeguides that referenced this pull request Jan 24, 2023
@waiting-for-dev waiting-for-dev added backport-v3.2 backport-v3.3 Backport this pull-request to v3.3 labels Feb 13, 2023
@github-actions
Copy link

💔 Some backports could not be created

Status Branch Result
v3.2
v3.1 An unhandled error occurred. Please see the logs for details
v3.3 Cherrypick failed because the selected commit (8281f98) is empty. Did you already backport this commit?

Manual backport

To create the backport manually run:

backport --pr 4858

Questions ?

Please refer to the Backport tool documentation and see the Github Action logs for details

@github-actions
Copy link

💔 Some backports could not be created

Status Branch Result
v3.2
v3.1 An unhandled error occurred. Please see the logs for details
v3.3 Cherrypick failed because the selected commit (8281f98) is empty. Did you already backport this commit?

Manual backport

To create the backport manually run:

backport --pr 4858

Questions ?

Please refer to the Backport tool documentation and see the Github Action logs for details

@github-actions
Copy link

💔 Some backports could not be created

Status Branch Result
v3.2
v3.1 An unhandled error occurred. Please see the logs for details
v3.3 Cherrypick failed because the selected commit (8281f98) is empty. Did you already backport this commit?

Manual backport

To create the backport manually run:

backport --pr 4858

Questions ?

Please refer to the Backport tool documentation and see the Github Action logs for details

waiting-for-dev pushed a commit to nebulab/solidus that referenced this pull request Mar 7, 2023
This will make unnecessary to wrap these definitions under `.to_prepare`
blocks.

Additionally the error message for unexpected keys has improved and
now lists both all the unexpected keys along with the expected keys,
mentioning the name associated to the definition.

Backports solidusio#4858 to v3.1
waiting-for-dev added a commit to solidusio/solidus_stripe that referenced this pull request Mar 7, 2023
There's no longer the need to call `.to_prepare`, as the issue has been
fixed upstream:

- v3.3: solidusio/solidus#4858
- v3.2: solidusio/solidus#4939
- v3.1: solidusio/solidus#4967
waiting-for-dev added a commit to solidusio/solidus_stripe that referenced this pull request Mar 7, 2023
There's no longer the need to call `.to_prepare`, as the issue has been
fixed upstream:

- v3.3: solidusio/solidus#4858
- v3.2: solidusio/solidus#4939
- v3.1: solidusio/solidus#4967
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport-v3.3 Backport this pull-request to v3.3 changelog:solidus_core Changes to the solidus_core gem type:enhancement Proposed or newly added feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants