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

Always return the result of APIResource#refresh in APIResource.retrieve #1473

Merged
merged 2 commits into from
Oct 23, 2024

Conversation

AnotherJoSmith
Copy link
Contributor

@AnotherJoSmith AnotherJoSmith commented Oct 21, 2024

This is somewhat of a bug report masked as a PR, since I'm not sure what I suggested is the desired solution based on the API design of ApiResource.refresh. If we think this is the best solution for now, I'm happy to add tests as well.

With the refactor of v13, there are now cases where self is not mutated in the call to refresh and instead a new object is returned. This change ensures that the new object is always returned by returning the result of refresh instead.

This case happens when the else branch of this method is triggered.

if Util.object_name_matches_class?(resp.data[:object], object.class)
object.send(:initialize_from,
resp.data, RequestOptions.persistable(req_opts), resp,
api_mode: :v1, requestor: self)
else
Util.convert_to_stripe_object_with_params(resp.data, params,
RequestOptions.persistable(req_opts),
resp, api_mode: :v1, requestor: self)
end

This happens if you defined a custom object that extends APIResource. For example, at Shopify we have an object like so:

module Stripe
  class ReservePlan < APIResource

  class << self
    def retrieve(id, opts = {})
      super
    end
  end
end

The retrieve method no longer works with the method for v13, since it doesn't return the result of the API call, since instance is not mutated in this case.

However even after the change in this PR, there is still a regression since calling super now returns a generic StripeObject. To be able to return an instance of our custom class, I had to change the code of retrieve to something like this:

def retrieve(id, opts = {})
  result = super
  construct_from(result.to_h, opts, result.last_response)
end

This is obviously not as clean as it was before. It's also a bit unintuitive to have a method called #refresh which returns a new StripeObject instance instead of mutating the existing instance, which seems like the intent of that method.

Changelog

  • Fix bug where we would not return the mutated self object when calling APIResource.retrieve, now it will always return the result of APIResource.refresh

Copy link

cla-assistant bot commented Oct 21, 2024

CLA assistant check
All committers have signed the CLA.

Copy link

cla-assistant bot commented Oct 21, 2024

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@AnotherJoSmith
Copy link
Contributor Author

@helenye-stripe
Copy link
Contributor

helenye-stripe commented Oct 23, 2024

Hi @AnotherJoSmith, sorry for the friction here! We changed this due to the change in behavior for StripeClient, but we did not realize this regression would occur. Do you mind adding tests and we will get this merged. I've also made a ticket to track this internally, and will track details for

there is still a regression since calling super now returns a generic StripeObject

this regression as well.

In the future I would recommend opening an issue and linking the PR to the issue -- we track user GH issues much more closely than user PRs!

With the refactor of v13, there are now cases where `self` is not
mutated in the call to refresh and instead a new object is returned.
This change ensures that the new object is always returned by returning
the result of refresh instead.
@AnotherJoSmith
Copy link
Contributor Author

@helenye-stripe Added a test (which I verified fails without my change).

I also updated the README which had outdated instructions on installing stripe-mock.

@helenye-stripe helenye-stripe merged commit 042918c into stripe:master Oct 23, 2024
14 checks passed
@AnotherJoSmith
Copy link
Contributor Author

@helenye-stripe Any chance you can release a new patch version? That will unblock our ability to upgrade this gem at Shopify.

@helenye-stripe
Copy link
Contributor

We're releasing soon - @jar-stripe will be taking care of this.

@helenye-stripe
Copy link
Contributor

@AnotherJoSmith This should be out in v13.0.2!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants