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

Introduce from_json as the inverse of to_json #326

Merged
merged 3 commits into from
Sep 6, 2024
Merged

Introduce from_json as the inverse of to_json #326

merged 3 commits into from
Sep 6, 2024

Conversation

pedropb
Copy link
Contributor

@pedropb pedropb commented Aug 13, 2024

The Money gem provides two JSON generating methods:

  • to_json generates a JSON-encoded String representation of the Money object.
  • as_json generates a JSON-encoded Hash representation of the Money object.

This PR introduces a class method that accepts any of these 2 JSON representations and generates a Money object from it.

Copy link
Contributor

@mkorostoff-shopify mkorostoff-shopify left a comment

Choose a reason for hiding this comment

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

overall I have no problem with these changes, just a couple of optional suggestions

@@ -74,6 +75,16 @@ def from_subunits(subunits, currency_iso, format: :iso4217)
new(value, currency)
end

def from_json(hash_or_string)
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if this might be a bit easier to follow with explicit, separate methods from_hash and from_json that each handle a single data type, rather than attempting to juggle types within a single method. It seems a slightly surprising result to have a method from_json that accepts an input which is not JSON.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The concern that from_json takes something that's not a JSON object is valid, but it's an ambiguity that already exists in the gem in to_json: void -> String vs as_json: void -> Hash.

I don't have a strong opinion but my line of thought was that the utility of a from_json that understands both JSON-encoded strings and JSON-encoded hashes was greater than having separate methods, which would leave a user guessing "which one do I have to use again?"

Copy link

Choose a reason for hiding this comment

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

If we look at how rails handles these:
to_json - JSON string representing a model
as_json - Hash representing a model
from_json - Sets the model attributes from a JSON string.

Based on convention I agree that from_json should expect a json String and if we needed to convert a hash we should have a from_hash.

Especially given our use of Sorbet I would expect the user to be aware if they needed one or the other.

Copy link
Contributor

@elfassy elfassy Aug 15, 2024

Choose a reason for hiding this comment

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

Let's start only with from_json (with a json string). Going from a hash to a Money object is trivial Money.new(hash[:amount], hash[:currency]) and doesn't really require an extra helper.

spec/money_spec.rb Outdated Show resolved Hide resolved
rosew
rosew previously requested changes Aug 15, 2024
@@ -74,6 +75,16 @@ def from_subunits(subunits, currency_iso, format: :iso4217)
new(value, currency)
end

def from_json(hash_or_string)
Copy link

Choose a reason for hiding this comment

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

If we look at how rails handles these:
to_json - JSON string representing a model
as_json - Hash representing a model
from_json - Sets the model attributes from a JSON string.

Based on convention I agree that from_json should expect a json String and if we needed to convert a hash we should have a from_hash.

Especially given our use of Sorbet I would expect the user to be aware if they needed one or the other.

@elfassy
Copy link
Contributor

elfassy commented Aug 26, 2024

@pedropb if you want to add just from_json (with a json string only) I can include it in the v3 release

@pedropb
Copy link
Contributor Author

pedropb commented Aug 26, 2024

Hey folks,

pushed some rebased commits. Here are the changes:

  • as requested: separate methods to handle distinct types from_json and from_hash.
  • new: aliased to_h as as_json
  • Even though it is trivial to create a Money object from a Hash, I kept the from_hash for symmetry (inverse of as_json). This is the use case that we currently have in our application with direct access to hash["value"], hash["currency"] and would like to get rid of.

lib/money/money.rb Outdated Show resolved Hide resolved
Copy link

@rosew rosew left a comment

Choose a reason for hiding this comment

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

LGTM

@pedropb pedropb merged commit 7a9de52 into main Sep 6, 2024
9 checks passed
@pedropb pedropb deleted the pb-from-json branch September 6, 2024 16:54
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.

4 participants