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" 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 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 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