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

new integration spec for rails 7 exhibiting failure when executing de… #569

Merged

Conversation

aflansburg
Copy link
Contributor

New integration spec for Rails 7 to exhibit failure mentioned in #559 when applying deep_transform_keys (or any deep_<op>_keys for that matter on Hashie::Dash or inheriting classes.

@dblock
Copy link
Member

dblock commented Nov 4, 2022

Did you expect more failures than this one @aflansburg?

  1) rails #deep_transform_keys sucessfully deep transforms keys
     Failure/Error:
       raise ArgumentError,
             "The property '#{property}' #{self.class.required_properties[property][:message]}"

     ArgumentError:
       The property 'foo_baz' is required for HashieDashKlass.
     # ./lib/hashie/dash.rb:222:in `fail_property_required_error!'
     # ./lib/hashie/dash.rb:214:in `assert_property_set!'
     # ./lib/hashie/dash.rb:209:in `block in assert_required_attributes_set!'
     # ./lib/hashie/dash.rb:208:in `each_key'
     # ./lib/hashie/dash.rb:208:in `assert_required_attributes_set!'
     # ./lib/hashie/dash.rb:183:in `update_attributes!'
     # ./lib/hashie/dash.rb:192:in `initialize_attributes'
     # ./lib/hashie/dash.rb:107:in `initialize'
     # ./spec/integration/rails_7/integration_spec.rb:50:in `block (3 levels) in <top (required)>'
     # ./spec/integration/rails_7/integration_spec.rb:13:in `block (2 levels) in <top (required)>'

I think we should mark that spec pending with a link to the issue, update CHANGELOG saying we added an integration test for Rails 7, and merge this PR so we have it.

That unless you can fix the issue?

@aflansburg
Copy link
Contributor Author

aflansburg commented Nov 7, 2022

Did you expect more failures than this one @aflansburg?
that was it!

@dblock

I think we should mark that spec pending with a link to the issue, update CHANGELOG saying we added an integration
test for Rails 7, and merge this PR so we have it.

yeah that makes sense -> 9033f06

That unless you can fix the issue?

short on time atm, but happy to look into it when able

@aflansburg
Copy link
Contributor Author

aflansburg commented Nov 7, 2022

@dblock not to muddy the waters with further commentary, but could this have something to do with this change here?

HashWithIndifferentAccess#deep_transform_keys` now returns a `HashWithIndifferentAccess` instead of a `Hash`.

This would also impact #deep_symbolize_keys also mentioned in #559

@michaelherold
Copy link
Member

I have looked into the failure here and while the example makes sense from a use perspective, the implementation is weird because Dash keys are always Symbols, but the test is doing deep_transform_keys(&:to_s). This is always invalid for a Dash.

I'm wondering what the correct behavior should be here - the expected behavior of failing to convert the keys, which is consistent with ActiveSupport's behavior? Or implicitly casting the result to a regular Hash, which would allow the method to work but would break the definition of ActiveSupport's method.

The latter would at least allow it to work, albeit inconsistently. The former doesn't make sense though because you wouldn't transform the keys of a Dash; that would make no sense since the entire point of a Dash is that it has coerced and validated keys.

An alternative would be to disable or no-op #deep_stringify_keys, #deep_stringify_keys!, #deep_symbolize_keys, #deep_symbolize_keys!, #deep_transform_keys, and #deep_transform_keys! in Rails 7+.

In fact, this should probably be universal for #transform_keys and #transform_keys! as well, though that would be strictly backward-incompatible.


A final alternative, and what I think might make the most sense would be to add a note to the readme for Dash that:

  1. Discusses why you don't want to transform keys on a Dash
  2. Gives a pattern to use dash.to_h.transform_keys or dash.with_indifferent_access.transform_keys in Rails. This is the only pattern that makes sense for a Dash since Dashes validate their properties

The downside to this approach is that there is undefined behavior for something like #deep_transform_keys since that iterates through an Enumerable that may contain a Dash, which leads to this bug.

There isn't a pretty solution that I see.

@aflansburg
Copy link
Contributor Author

An alternative would be to disable or no-op #deep_stringify_keys, #deep_stringify_keys!, #deep_symbolize_keys, #deep_symbolize_keys!, #deep_transform_keys, and #deep_transform_keys! in Rails 7+.

TL;DR - needing to use #deep_transform_keys on a Dash is probably an edge case. We really don't need it after digging deeper into our use case (not my code).

@michaelherold - personally, this seems very reasonable. Our use case is building request and response bodies using Hashie::Trash. We then .to_json the hash after doing the deep transforms on the keys. As I was not previously very familiar with Hashie, I now notice in the documentation we can do the basic key transforms we needed using the documented PropertyTranslation and there's really no need to do something like:

    def body
      @body ||= req.to_hash.deep_transform_keys { |key| key.to_s.camelize(:lower).to_sym }.to_json
    end

Copy link
Member

@dblock dblock left a comment

Choose a reason for hiding this comment

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

I made some nitpicky comments. I'd like to merge this, thanks for hanging in here!

CHANGELOG.md Outdated
@@ -37,7 +37,7 @@ Any violations of this scheme are considered to be bugs.

### Miscellaneous

* Your contribution here.
Copy link
Member

Choose a reason for hiding this comment

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

Put this back please?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My apologies - just circling back to this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

CHANGELOG.md Outdated
@@ -37,7 +37,7 @@ Any violations of this scheme are considered to be bugs.

### Miscellaneous

* Your contribution here.
* [#569](https://github.com/hashie/hashie/pull/569): Added pending spec related to issue [#559](https://github.com/hashie/hashie/issues/559) when calling `#deep_transform_keys` on instance of `Hashie::Dash` w/ Rails 7 - [@aflansburg](https://github.com/aflansburg)
Copy link
Member

Choose a reason for hiding this comment

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

This is missing a period at the end.

I think the change should be "Added support for Rails 7" because by adding specs we say that we support it. There are bugs, but c'est la vie.

Copy link
Contributor Author

Choose a reason for hiding this comment

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


context '#deep_transform_keys' do
it 'sucessfully deep transforms keys' do
class HashieDashKlass < Hashie::Dash
Copy link
Member

Choose a reason for hiding this comment

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

I think these are global. I would do this to avoid polluting namespaces:

let(:klass) do
   Class.new(Hashie::Dash) do
     property ...
   end
end

Copy link
Contributor Author

Choose a reason for hiding this comment

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

end

context '#deep_transform_keys' do
it 'sucessfully deep transforms keys' do
Copy link
Member

Choose a reason for hiding this comment

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

Move pending here, I think we use that pattern elsewhere, so pending "deep transforms keys".

Copy link
Contributor Author

@aflansburg aflansburg Dec 6, 2022

Choose a reason for hiding this comment

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

@dblock dblock merged commit 6fabbfd into hashie:master Dec 6, 2022
@dblock
Copy link
Member

dblock commented Dec 6, 2022

Fixed up CHANGELOG, put the issue number in pending spec and merged, thx.

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.

None yet

3 participants