-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Let the PriceSelector return a Spree::Price #3925
Let the PriceSelector return a Spree::Price #3925
Conversation
083d551
to
14fcc0e
Compare
14fcc0e
to
5d03314
Compare
It also occurred to me that it's perhaps the case that the reason that this returns a I don't think this is an issue, since you can just return an unpersisted price, but it should be understood that this API is allowed to return unpersisted prices to allow for that use case. 🤔 |
# a Spree::Money | ||
# @return [Spree::Price, Spree::Money, nil] The most specific price for | ||
# this set of pricing options in the desired format. | ||
def price_for(price_options, return_price: false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit concerned by this approach to deprecating the method. Our approach to major upgrades is to ensure that someone who's on the latest 3.x will always be able to update to 4.0 without touching their code as long as they don't get any deprecation warnings.
Unless I'm missing something, with this change people will have to call price_for(..., return_price: true)
in the latest 3.x in order not to get the deprecation warning. But then, in 4.0, we are going to remove the return_price:
argument altogether, and anyone who passes it will start getting an error.
In other words, people who upgrade from the latest 3.x to 4.0 will have to change something in their code in order to complete the upgrade, which is something we should try to avoid if at all possible.
How about removing this, and only using the value of Spree::Config. price_selector_returns_price
instead? It's also more straightforward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea was to deprecated return_price
after the change in the next major (4.0). This kind of deprecation allows keeping the system working for example if the host application switched to returning price but some extensions don't.
I'm also ok using Spree::Config. price_selector_returns_price
alone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, I'd not really considered this. So @kennyadsl are you thinking we do this:
- In 3.x you get a deprecation warning if you use the
return_price: false
behaviour, but the behaviour remains. - In 4.x we remove the
return_price: false
behaviour and you get a deprecation warning if you passreturn_price:
to the method. - In 5.x we remove the
return_price:
argument.
That's not unreasonable, but 5.0 seems so far in the distance. 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what I was thinking but, totally unrelated, I think we can change the removal deprecation process starting from Solidus 3.0 so that we are allowed to remove deprecated code in the next minor version. That's what Rails does, and also (I discovered this yesterday 😓) what we kinda state here:
We would like to also follow the Rails approach: deprecating functionality in one minor version and removing it in the next.
Anyway, I think @aldesantis has a valid proposal to avoid this parameter at all, we were discussing it yesterday and I guess he will post some comments soon.
@swively thanks, I think the change makes sense but the deprecation strategy should probably be adjusted a little bit. Also, we'll have to address a bunch of deprecation warnings that this change causes in the Solidus codebase instead — the calling code will have to be updated in order to use the As an alternative, have you also considered simply implementing a new price selector class that returns a Also, to elaborate a bit on what @jarednorman said, we use a custom price selector for one of our clients to (somewhat) cleanly implement grandfathered pricing in a subscription-based app: our price selector checks the product and the user and returns either a |
Having seen a few client projects encounter issues with the price selector returning a To avoid forcing developer intervention when bumping to 4.0, I could remove the deprecation altogether and just let this method's return value be controlled via the config/flag, but I also think that the method in its current state is misleading and not as useful as it would be if it just returned a price object. Happy to go either way on this, the less impactful option being to remove the deprecation and leave it up to the user to configure the method to suit their use case. |
I think just using the global configuration would be better, since it doesn't create more work for us and our users in the future to also remove the new method parameter. @jarednorman @kennyadsl what do you think? Do you see any drawbacks? Also, @swively, would you be able to share some situations where returning a |
@aldesantis I've encountered it on two client projects in the last month. The first was using the sales prices extension, which has the sale price for a variant on the On a different project they used partial prices for items that are part of a bundle, so each item would have a regular standalone price, as well as a |
@swively after discussing the deprecation approach for this with @kennyadsl, we decided adding a new method may be the best path for moving forward. The additional parameter doesn't play well with a situation where someone has implemented their custom price selector, without knowing that it needs to comply with the You could add a The only concern is properly handling a situation where someone has implemented their own price selector and has only implemented To fix that, you might want to also implement Finally, you would update all the places in Solidus where we call Something else to keep in mind: |
@swively sorry, my fault for initially pointing you in a path that is not ideal. 🙏 |
Ah, that's a good catch. I had not thought of that. I don't love the name |
Yeah, to be honest it's the only one we could think of. 🤷 Open to better suggestions. One thing we should keep in mind is that we're out of names for deprecating that method, so let's make really sure we get it right this time. |
Yeah, I think in one app I used |
5d03314
to
e00feeb
Compare
b776715
to
776cdd1
Compare
776cdd1
to
17a0dad
Compare
The price_for method does not return a Spree::Price as described. Instead it does some frontend work and returns a Spree::Money, limiting the usability of this method, as the price record itself can have useful information on it. This deprecates the existing method in favor of one that returns a Spree::Price.
We need to safely ensure the new price_for_options method in the price selector will not break for those that have a custom price selector. If the new method is defined in the price selector class this will behave normally, and if their customization does not allow for it, we will instead return an unpersisted Spree::Price from the Spree::Money object that the deprecated price_for method returns. Spree::Product can now delegate price_for_options to master variant
The #price_for method will be deprecated in favor of the price_for_options method, which returns a Spree::Price. Converting the price to a Spree::Money object is now a frontend concern.
17a0dad
to
fe4e0a5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this PR is perfect! 🙏 🙏
We are going to merge this as soon as 3.0 is released so it will be part of 3.1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@swively thanks!
PR approved by other core team members.
Please, use price_for_options now. Ref solidusio#3925
Please, use price_for_options now. Ref solidusio#3925
Please, use price_for_options now. Ref solidusio#3925
Please, use price_for_options now. Ref solidusio#3925
Please, use price_for_options now. Ref solidusio#3925
Please, use price_for_options now. Ref solidusio#3925
Please, use price_for_options now. Ref solidusio#3925
Description
Issue laid out in this discussion
The
Variant::PriceSelector
currently returns aSpree::Money
, which is misleading and somewhat limiting.The
Spree::Price
model is useful for its ability to be extended to support things like sales prices, partial prices, etc.Checklist: