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

Support Rails 6.1 ActiveModel::Errors #62

Merged
merged 8 commits into from
Nov 25, 2021

Conversation

rewritten
Copy link

@rewritten rewritten commented Sep 20, 2021

ActiveModel::Errors class has been revamped and it is now not compatible with most of the existing (and already deprecated) idioms (adding errors with record.errors[:attr] << 'My error', mutating the hash returned by #messages, and a big chunk of the remaining API is deprecated.

This change aims to support both pre-6.1 and post 6.1 versions with as little conditionals as possible.

It also includes a patch to ActiveData's nested validator, which attempts to mutate directly the error hash (which is not a hash anymore). A similar patch is available at pyromaniac/active_data#76.

Review

Pre-merge checklist

  • The PR relates to a single subject with a clear title and description in grammatically correct, complete sentences.
  • Verify that feature branch is up-to-date with master (if not - rebase it).
  • Double check the quality of commit messages.
  • Squash related commits together.

@rewritten
Copy link
Author

Coverage fails expectedly, because one of the branches in lib/granite/action/preconditions/embedded_precondition.rb is never used…

@rewritten
Copy link
Author

Do you need to keep compatibility with ruby 2.4?

@rewritten rewritten force-pushed the activemodel-errors-rails-6-1 branch from 4789e97 to b76443c Compare November 9, 2021 09:25
@ozeron ozeron requested review from andriusch and ojab and removed request for andriusch November 10, 2021 15:15
@rewritten rewritten force-pushed the activemodel-errors-rails-6-1 branch from b76443c to 145ac1a Compare November 24, 2021 15:23
@rewritten rewritten force-pushed the activemodel-errors-rails-6-1 branch from 65834ea to 051a41d Compare November 24, 2021 15:32
@rewritten rewritten requested a review from jodosha November 24, 2021 16:15
Comment on lines +64 to 76
if ActiveModel.version < Gem::Version.new('6.1.0')
def merge_errors(other_errors)
errors.messages.deep_merge!(other_errors.messages) do |_, this, other|
(this + other).uniq
end
end
else
def merge_errors(other_errors)
other_errors.each do |error|
errors.import(error) unless errors.added?(error.attribute, error)
end
end
end
Copy link
Author

Choose a reason for hiding this comment

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

This branching is the reason coverage has decreased. Only one of the two branches will ever be used in a single test run.

Anyway, the tests run in ruby 2.4 use activemodel 5, so the legacy execution branch is covered.

@@ -43,13 +43,13 @@ def execute_perform!(*)
specify do
expect do
expect { action.perform! }.to raise_validation_error.on_attribute(:raise_error)
end.to fail_with('expected to raise validation error on attribute :raise_error, but raised {:base=>[{:error=>:some_error}], :raise_error=>[]}')
end.to fail_with(include 'expected to raise validation error on attribute :raise_error, but raised {:base=>[{:error=>:some_error}]')
Copy link
Author

Choose a reason for hiding this comment

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

The extra reported error was an artifact due to older activemodel initializing a message array on access (and our usage of deep_merge!). Test is changed to only check the relevant part of the message.

@jodosha jodosha added the enhancement New feature or request label Nov 24, 2021
Copy link
Contributor

@jodosha jodosha left a comment

Choose a reason for hiding this comment

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

@rewritten Code LGTM. Could you please clarify the gemspec / Gemfile question? Thanks 😄

Gemfile Outdated

gem 'active_data', github: 'toptal/active_data', branch: 'master'

gem 'activerecord', '>= 5.0', '< 7'
Copy link
Contributor

Choose a reason for hiding this comment

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

@rewritten Why this change?

Having dev dependencies in gemspec has the benefit of being compatible with the rest of the ecosystem. E.g. Rubygems maps reverse deps for a gem, by analysing gemspec files.

Unless there is a valid reason for this, I would ask you to revert this change. Thanks. 😄

Copy link
Author

Choose a reason for hiding this comment

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

Ok. But rubygems never uses development dependencies when resolving transitive deps. I don't know where else the development dependencies are used (except for rubygems website).

Copy link
Author

Choose a reason for hiding this comment

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

For reference, Marc-André answer to the same topic in What are the practical advantages of using add_development_dependency in .gemspec?

It's not clear there is any.

In theory, RubyGems has the information necessary to run tests with add_development_dependency and test_files (see this question).

Some believe that this should be outside the scope of RubyGems (see this huge thread).

In practice, there is currently no real advantage, and the fact that RubyGems still installs test files by default is a drawback, as might be the lack of flexibility that Gemfile offers.

@rewritten rewritten requested a review from jodosha November 24, 2021 17:14
Copy link
Contributor

@jodosha jodosha left a comment

Choose a reason for hiding this comment

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

@rewritten Thanks for all the patience. You did an excellent job. 👍

@rewritten rewritten merged commit 4f6424e into master Nov 25, 2021
@rewritten rewritten deleted the activemodel-errors-rails-6-1 branch November 25, 2021 09:52
@@ -13,12 +13,12 @@ Gem::Specification.new do |s|
s.files = `git ls-files`.split("\n").grep(/\A(app|lib|config|LICENSE)/)
s.license = 'MIT'

s.add_runtime_dependency 'actionpack', '>= 5.1', '< 6.1'
s.add_runtime_dependency 'actionpack', '>= 5.1', '< 7'
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks bad without check for rails+active_data versions :/
Right now granite+rails-6.1 would just fail in unexpected places without knowledge that active_data from some-non-upstream git repo should be used.

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

Successfully merging this pull request may close these issues.

3 participants