From d34d932f06d4cc68a8db118eaad2c8903bdb4ea6 Mon Sep 17 00:00:00 2001 From: "yuuji.yaginuma" Date: Thu, 28 Jan 2021 11:50:50 +0900 Subject: [PATCH 1/4] Test against Rails 6.1 --- .travis.yml | 1 + Gemfile | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 21234b6..2db6cd8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,7 @@ rvm: services: - mongodb env: + - "RAILS_VERSION=6.1.0" - "RAILS_VERSION=6.0.0" - "RAILS_VERSION=5.2.0" - "RAILS_VERSION=5.1.0" diff --git a/Gemfile b/Gemfile index db12380..38a8920 100644 --- a/Gemfile +++ b/Gemfile @@ -20,12 +20,12 @@ rails_version = ENV.fetch("RAILS_VERSION", "6.0.0") # bored of wrestling with rails... -gem("mongoid", "< 7.0") unless rails_version.include?('6.0') +gem("mongoid", "< 7.0") unless rails_version.to_i >= 6 gem "activerecord", "~> #{rails_version}" gem "railties", "~> #{rails_version}" -if rails_version.include?('6.0') +if rails_version.to_i >= 6 gem "sqlite3", "~> 1.4" else gem "sqlite3", "~> 1.3", "< 1.4" From 250b4b0e68f8d386268bb45036bc01031cb440b3 Mon Sep 17 00:00:00 2001 From: "yuuji.yaginuma" Date: Wed, 10 Feb 2021 11:00:49 +0900 Subject: [PATCH 2/4] Implement `Reform::Contract::Result#filter_for` to support for Rails 6.1 In Rails 6.1, `messages` is an instance of `ActiveModel::DeprecationHandlingMessageArray`. So can't handle with the Reform's `filter_for`. --- lib/reform/active_record.rb | 1 + lib/reform/form/active_model/result.rb | 15 +++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 lib/reform/form/active_model/result.rb diff --git a/lib/reform/active_record.rb b/lib/reform/active_record.rb index d0bbb34..8309918 100644 --- a/lib/reform/active_record.rb +++ b/lib/reform/active_record.rb @@ -2,3 +2,4 @@ require "reform/form/active_model" require "reform/form/active_record" require "reform/form/active_model/model_reflections" # only load this in AR context as simple_form currently is bound to AR. +require "reform/form/active_model/result" diff --git a/lib/reform/form/active_model/result.rb b/lib/reform/form/active_model/result.rb new file mode 100644 index 0000000..d37560b --- /dev/null +++ b/lib/reform/form/active_model/result.rb @@ -0,0 +1,15 @@ +class Reform::Contract::Result + private + + def filter_for(method, *args) + @results.collect { |r| r.public_send(method, *args).to_h } + .inject({}) { |hah, err| hah.merge(err) { |key, old_v, new_v| (new_v.is_a?(Array) ? (old_v |= new_v) : old_v.merge(new_v)) } } + .find_all { |k, v| # filter :nested=>{:something=>["too nested!"]} #DISCUSS: do we want that here? + if v.is_a?(Hash) + nested_errors = v.select { |attr_key, val| attr_key.is_a?(Integer) && val.is_a?(Array) && val.any? } + v = nested_errors.to_a if nested_errors.any? + end + v.is_a?(Array) || v.class.to_s == "ActiveModel::DeprecationHandlingMessageArray" + }.to_h + end +end From b43dd5c2aa65d9d6b8a7aec95351cf841f42907e Mon Sep 17 00:00:00 2001 From: "yuuji.yaginuma" Date: Wed, 10 Feb 2021 11:11:30 +0900 Subject: [PATCH 3/4] Convert error message to a proper format when adding Now `ActiveModel::Errors#add` returns an instance of `ActiveModel::Error`. So can't use it as is. --- lib/reform/form/active_model/validations.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/reform/form/active_model/validations.rb b/lib/reform/form/active_model/validations.rb index 889aa66..34a3b66 100644 --- a/lib/reform/form/active_model/validations.rb +++ b/lib/reform/form/active_model/validations.rb @@ -143,7 +143,8 @@ def to_s def add(key, error_text) # use rails magic to get the correct error_text and make sure we still update details and fields - text = @amv_errors.add(key, error_text) + error = @amv_errors.add(key, error_text) + error = [error.message] unless error.is_a?(Array) # using error_text instead of text to either keep the symbol which will be # magically replaced with the translate or directly the string - this is also @@ -153,7 +154,7 @@ def add(key, error_text) # but since messages method is actually already defined in `Reform::Contract::Result::Errors # we need to update the @dotted_errors instance variable to add or merge a new error - @dotted_errors.key?(key) ? @dotted_errors[key] |= text : @dotted_errors[key] = text + @dotted_errors.key?(key) ? @dotted_errors[key] |= error : @dotted_errors[key] = error instance_variable_set(:@dotted_errors, @dotted_errors) end From bc73f899595e32430c6198480e4f40eefd6f649c Mon Sep 17 00:00:00 2001 From: "yuuji.yaginuma" Date: Wed, 10 Feb 2021 11:17:34 +0900 Subject: [PATCH 4/4] Follow new behavior of Rails 6.1 `ActiveModel::Errors#messages` now only returns error attributes. --- test/activemodel_validation_test.rb | 12 ++++++++++-- test/test_helper.rb | 4 ++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/test/activemodel_validation_test.rb b/test/activemodel_validation_test.rb index 06eafd9..dc249a3 100644 --- a/test/activemodel_validation_test.rb +++ b/test/activemodel_validation_test.rb @@ -265,7 +265,11 @@ def email_present? # valid. it "is valid" do _(form.validate({ username: "not yo", email: "bla" })).must_equal true - _(form.errors.messages).must_equal({:username=>[], :email=>[]}) + if self.class.rails_greater_6_0? + _(form.errors.messages).must_equal({}) + else + _(form.errors.messages).must_equal({:username=>[], :email=>[]}) + end if self.class.rails5? _(form.errors.details.inspect).must_equal "{}" end @@ -312,7 +316,11 @@ def email_present? _(form.errors.messages).must_equal(email: ["can't be blank", "fill it out!"], username: ["not ok", "must be yo"], policy: ["error_text", "another error"]) # keep added errors after validate _(form.validate(username: "username", email: "email@email.com")).must_equal false - _(form.errors.messages).must_equal(policy: ["error_text", "another error"], username: [], email: []) + if self.class.rails_greater_6_0? + _(form.errors.messages).must_equal(policy: ["error_text", "another error"]) + else + _(form.errors.messages).must_equal(policy: ["error_text", "another error"], username: [], email: []) + end _(form.errors.added?(:policy, "error_text")).must_equal true _(form.errors.added?(:policy, "another error")).must_equal true _(form.errors.details).must_equal( diff --git a/test/test_helper.rb b/test/test_helper.rb index 3963d3e..c77ce70 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -39,6 +39,10 @@ class Album < ActiveRecord::Base load "#{File.dirname(__FILE__)}/support/schema.rb" Minitest::Spec.class_eval do + def self.rails_greater_6_0? + (::ActiveModel::VERSION::MAJOR == 6 and ::ActiveModel::VERSION::MINOR >= 1) || (::ActiveModel::VERSION::MAJOR >= 7) + end + def self.rails5? ::ActiveModel::VERSION::MAJOR.in? [5,6] end