reform 2.0.5 → 2.1.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -1
  3. data/CHANGES.md +12 -0
  4. data/Gemfile +12 -2
  5. data/README.md +9 -14
  6. data/Rakefile +1 -1
  7. data/database.sqlite3 +0 -0
  8. data/lib/reform.rb +1 -0
  9. data/lib/reform/contract.rb +13 -20
  10. data/lib/reform/contract/validate.rb +9 -7
  11. data/lib/reform/form.rb +45 -31
  12. data/lib/reform/form/active_model.rb +10 -10
  13. data/lib/reform/form/active_model/form_builder_methods.rb +5 -4
  14. data/lib/reform/form/active_model/model_reflections.rb +2 -2
  15. data/lib/reform/form/active_model/model_validations.rb +3 -3
  16. data/lib/reform/form/active_model/validations.rb +49 -32
  17. data/lib/reform/form/dry.rb +55 -0
  18. data/lib/reform/form/lotus.rb +4 -1
  19. data/lib/reform/form/module.rb +3 -17
  20. data/lib/reform/form/multi_parameter_attributes.rb +0 -9
  21. data/lib/reform/form/populator.rb +72 -30
  22. data/lib/reform/form/validate.rb +19 -43
  23. data/lib/reform/form/validation/unique_validator.rb +39 -6
  24. data/lib/reform/validation.rb +40 -0
  25. data/lib/reform/validation/groups.rb +73 -0
  26. data/lib/reform/version.rb +1 -1
  27. data/reform.gemspec +3 -1
  28. data/test/active_record_test.rb +2 -0
  29. data/test/contract_test.rb +2 -2
  30. data/test/deprecation_test.rb +27 -0
  31. data/test/deserialize_test.rb +29 -8
  32. data/test/dummy/config/locales/en.yml +4 -1
  33. data/test/errors_test.rb +4 -4
  34. data/test/feature_test.rb +2 -2
  35. data/test/fixtures/dry_error_messages.yml +43 -0
  36. data/test/form_builder_test.rb +10 -8
  37. data/test/form_test.rb +1 -36
  38. data/test/inherit_test.rb +20 -8
  39. data/test/module_test.rb +2 -30
  40. data/test/parse_pipeline_test.rb +15 -0
  41. data/test/populate_test.rb +41 -12
  42. data/test/populator_skip_test.rb +28 -0
  43. data/test/reform_test.rb +1 -1
  44. data/test/skip_if_test.rb +10 -3
  45. data/test/test_helper.rb +11 -2
  46. data/test/unique_test.rb +72 -1
  47. data/test/validate_test.rb +6 -7
  48. data/test/validation/activemodel_validation_test.rb +252 -0
  49. data/test/validation/dry_validation_test.rb +330 -0
  50. metadata +63 -10
  51. data/lib/reform/schema.rb +0 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a7b6c745acf6fc96e9d5c0291d4fa64df5be3c92
4
- data.tar.gz: 0304e04e195f525af7aed8081c87a328885c2581
3
+ metadata.gz: 6fd73b0dc59751240c4ec4518477b225c5becf81
4
+ data.tar.gz: 1a6a1e8eba9f547424e533698129299afbdc8a93
5
5
  SHA512:
6
- metadata.gz: 1070cf32ba255c0b08d5b0dc7bc3a666cd1a515fe627e77af2168519908fe9a0680b132cdc2e77e512cd346c1b458051bc5c1e055db31bcc101ac718dfca8bf4
7
- data.tar.gz: 42777ea0870fa57d5eb6c87df3cda716bd6eff0f0c479e50610df969845b089c6dcaa366ab1e14c66484c1980fbf621dd045463cc2ae357d5e8fbbcc3f13fdf8
6
+ metadata.gz: 59066ba1ed67fc72da96561cb77f4dfcf3750c2840ce825b55344851476a09feba5e8222b2aa75d560014c027ce313f2896ad49b651c6de7a52ede2cee0db854
7
+ data.tar.gz: 57f67e136f2e7ea8c99db1baaab671a26ae6ebbfb62066564048c38ccd3bbc8b1846a54733b9f5629bb01d32085470649fa4f7c255f35042eab5f7fc9b990b69
data/.travis.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2.0
3
+ - 2.2.3
4
4
  - 1.9.3
5
5
  services:
6
6
  - mongodb
@@ -15,3 +15,5 @@ matrix:
15
15
  fast_finish: true
16
16
  allow_failures:
17
17
  - rvm: 1.9.3
18
+ before_install:
19
+ - gem install bundler
data/CHANGES.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## 2.1
2
+
3
+ ### Awesomeness
4
+
5
+ * You can now have `:populator` for scalar properties, too. This allows "parsing code" per property which is super helpful to structure your deserialization.
6
+ * `:populator` can be a method name, as in `populator: :populate_authors!`.
7
+ * Populators can now skip deserialization of a nested fragment using `skip!`. [Learn more here](http://trailblazer.to/gems/reform/populator.html).
8
+ * Added basic support for dry-validation as a future replacement for ActiveModel::Validation. Note that this is still experimental, but feel free to test.
9
+
10
+ * :populator ->(options) or ->(fragment:, model:, **o)
11
+ * `ActiveModel::Validator` prevents Rails from adding methods to it. This makes `acceptance` and `confirmation` validations work properly.
12
+
1
13
  ## 2.0.5
2
14
 
3
15
  * `ActiveModel::Validator` now delegates all methods properly to the form. It used to crashed with properties called `format` or other private `Object` methods.
data/Gemfile CHANGED
@@ -2,6 +2,16 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- #gem 'representable', path: "../representable"
5
+
6
+ # gem "representable", "2.4.0.rc5"
7
+ # gem 'representable', path: "../representable"
8
+ # # gem 'representable', github: "apotonick/representable"
6
9
  # gem "disposable", path: "../disposable"
7
- # gem "disposable", github: "apotonick/disposable"
10
+ # gem "disposable", github: "apotonick/disposable"
11
+
12
+
13
+ # gem "declarative", path: "../declarative"
14
+
15
+ gem "minitest-line"
16
+ gem 'dry-validation'
17
+ gem 'byebug'
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # Reform
2
2
 
3
+ [![Gitter Chat](https://badges.gitter.im/trailblazer/chat.svg)](https://gitter.im/trailblazer/chat)
3
4
  [![Build
4
5
  Status](https://travis-ci.org/apotonick/reform.svg)](https://travis-ci.org/apotonick/reform)
5
6
  [![Gem Version](https://badge.fury.io/rb/reform.svg)](http://badge.fury.io/rb/reform)
@@ -12,22 +13,16 @@ Although reform can be used in any Ruby framework, it comes with [Rails support]
12
13
 
13
14
  ## This is not Reform 1.x!
14
15
 
15
- Temporary note: This is the README and API for Reform 2. On the public API, only a few tiny things have changed. When in trouble, join us on the IRC (Freenode) #trailblazer channel.
16
+ Temporary note: This is the README and API for Reform 2. On the public API, only a few tiny things have changed. Here are the [Reform 1.2 docs](https://github.com/apotonick/reform/blob/v1.2.6/README.md).
16
17
 
17
- [Full documentation for Reform](http://trailblazerb.org/gems/reform) is available online, or support us and grab the [Trailblazer book](https://leanpub.com/trailblazer).
18
+ Anyway, please upgrade and _report problems_ and do not simply assume that we will magically find out what needs to get fixed. When in trouble, join us on [Gitter](https://gitter.im/trailblazer/chat).
19
+
20
+ [Full documentation for Reform](http://trailblazer.to/gems/reform) is available online, or support us and grab the [Trailblazer book](https://leanpub.com/trailblazer). There is an [Upgrading Guide](http://trailblazer.to/gems/reform/upgrading-guide.html) to help you migrate from Reform 1.x.
18
21
 
19
22
  ## Disposable
20
23
 
21
24
  Every form in Reform is a _twin_. Twins are non-persistent domain objects from the [Disposable gem](https://github.com/apotonick/disposable). All features of Disposable, like renaming fields, change tracking, etc. are available in Reform, too.
22
25
 
23
- <!--
24
- ## ActiveModel
25
-
26
- **WARNING: Reform will soon drop support for ActiveModel validations.**
27
-
28
- This is mostly to save my mental integrity. The amount of problems we have in Reform with ActiveModel's poor object design, its lack of interfaces and encapsulation do outweigh the benefits. Please consider using Lotus::Validations instead, which will soon be mature enough to replace this dinosaur.
29
- -->
30
-
31
26
  ## Defining Forms
32
27
 
33
28
  Forms are defined in separate classes. Often, these classes partially map to a model.
@@ -288,7 +283,7 @@ class AlbumForm < Reform::Form
288
283
  end
289
284
  ```
290
285
 
291
- Reform also allows to completely override population using the `:populator` options. This is [documented here](http://trailblazerb.org/gems/reform/populators.html), and also in the Trailblazer book.
286
+ Reform also allows to completely override population using the `:populator` options. This is [documented here](http://trailblazer.to/gems/reform/populators.html), and also in the Trailblazer book.
292
287
 
293
288
  ## Installation
294
289
 
@@ -739,7 +734,7 @@ class SongForm < Reform::Form
739
734
  end
740
735
  ```
741
736
 
742
- Be warned that we _do not_ encourage copying validations. You should rather move validation code into forms and not work on your model directly anymore.
737
+ Be warned that we _do not_ encourage copying validations. You should rather move validation code into forms and not work on your model directly anymore. Also, please note that the ```copy_validations_from``` line _must_ go below your property definitions for the validations to copy correctly.
743
738
 
744
739
  ## Agnosticism: Mapping Data
745
740
 
@@ -799,7 +794,7 @@ class SongForm < Reform::Form
799
794
 
800
795
  Both ActiveRecord and Mongoid modules will support "native" uniqueness support from the model class when you use `validates_uniqueness_of`. They will provide options like `:scope`, etc.
801
796
 
802
- You're encouraged to use Reform's non-writing `unique: true` validation, though. [Learn more](http://trailblazerb.org/gems/reform/validation.html)
797
+ You're encouraged to use Reform's non-writing `unique: true` validation, though. [Learn more](http://trailblazer.to/gems/reform/validation.html)
803
798
 
804
799
  ## ActiveModel Compliance
805
800
 
@@ -981,7 +976,7 @@ Note that this still runs validations for the property, though.
981
976
 
982
977
  ### Prepopulating Forms
983
978
 
984
- Docs: http://trailblazerb.org/gems/reform/prepopulator.html
979
+ Docs: http://trailblazer.to/gems/reform/prepopulator.html
985
980
 
986
981
  When rendering a new form for an empty object, nested forms won't show up. The [Trailblazer book, chapter 5](https://leanpub.com/trailblazer), discusses this in detail.
987
982
 
data/Rakefile CHANGED
@@ -4,7 +4,7 @@ require 'rake/testtask'
4
4
  task :default => [:test]
5
5
  Rake::TestTask.new(:test) do |test|
6
6
  test.libs << 'test'
7
- test.test_files = FileList['test/*_test.rb']
7
+ test.test_files = FileList['test/*_test.rb'] + FileList["test/validation/*_test.rb"]
8
8
 
9
9
  # test.test_files = ["test/changed_test.rb",
10
10
  # "test/coercion_test.rb",
data/database.sqlite3 CHANGED
Binary file
data/lib/reform.rb CHANGED
@@ -4,6 +4,7 @@ module Reform
4
4
  end
5
5
  end
6
6
 
7
+ require "disposable"
7
8
  require "reform/contract"
8
9
  require "reform/form"
9
10
  require "reform/form/composition"
@@ -1,7 +1,4 @@
1
1
  require "uber/inheritable_attr"
2
- require "disposable/twin"
3
- require "disposable/twin/setup"
4
- require "disposable/twin/default"
5
2
 
6
3
  module Reform
7
4
  # Define your form structure and its validations. Instantiate it with a model,
@@ -14,10 +11,8 @@ module Reform
14
11
  feature Setup::SkipSetter
15
12
  feature Default
16
13
 
17
- representer_class.instance_eval do
18
- def default_inline_class
19
- Contract
20
- end
14
+ def self.default_nested_class
15
+ Contract
21
16
  end
22
17
 
23
18
  def self.property(name, options={}, &block)
@@ -25,10 +20,8 @@ module Reform
25
20
  options[:twin] = twin
26
21
  end
27
22
 
28
- options[:pass_options] = true
29
-
30
23
  if validates_options = options[:validates]
31
- validates name, validates_options.dup # .dup for RAils 3.x.
24
+ validates name, validates_options
32
25
  end
33
26
 
34
27
  super
@@ -43,13 +36,16 @@ module Reform
43
36
  require 'reform/contract/validate'
44
37
  include Reform::Contract::Validate
45
38
 
39
+ require "reform/validation"
40
+ include Reform::Validation # ::validates and #valid?
46
41
 
47
- module ValidatesWarning
48
- def validates(*)
49
- raise "[Reform] Please include either Reform::Form::ActiveModel::Validations or Reform::Form::Lotus in your form class."
50
- end
51
- end
52
- extend ValidatesWarning
42
+
43
+ # module ValidatesWarning
44
+ # def validates(*)
45
+ # raise "[Reform] Please include either Reform::Form::ActiveModel::Validations or Reform::Form::Lotus in your form class."
46
+ # end
47
+ # end
48
+ # extend ValidatesWarning
53
49
 
54
50
  private
55
51
  # DISCUSS: separate file?
@@ -63,7 +59,7 @@ module Reform
63
59
  end
64
60
 
65
61
  def self.options_for(name)
66
- representer_class.representable_attrs.get(name)
62
+ definitions.get(name)
67
63
  end
68
64
  include Readonly
69
65
 
@@ -71,8 +67,5 @@ module Reform
71
67
  def self.clone # TODO: test. THIS IS ONLY FOR Trailblazer when contract gets cloned in suboperation.
72
68
  Class.new(self)
73
69
  end
74
-
75
- require "reform/schema"
76
- extend Reform::Schema
77
70
  end
78
71
  end
@@ -1,8 +1,14 @@
1
1
  module Reform::Contract::Validate
2
+ def initialize(*)
3
+ super
4
+ @errors = build_errors
5
+ end
6
+
7
+ attr_reader :errors
8
+
2
9
  def validate
3
- validate!(errs=build_errors, [])
10
+ validate!(errors, [])
4
11
 
5
- @errors = errs
6
12
  errors.empty?
7
13
  end
8
14
 
@@ -15,17 +21,13 @@ module Reform::Contract::Validate
15
21
  errors.merge!(nested_errors, [])
16
22
  end
17
23
 
18
- def errors
19
- @errors ||= build_errors
20
- end
21
-
22
24
  private
23
25
 
24
26
  # runs form.validate! on all nested forms
25
27
  def validate_nested!(errors, prefixes)
26
28
  schema.each(twin: true) do |dfn|
27
29
  # recursively call valid? on nested form.
28
- Disposable::Twin::PropertyProcessor.new(dfn, self).() { |form| form.validate!(errors, prefixes+[dfn.name]) }
30
+ Disposable::Twin::PropertyProcessor.new(dfn, self).() { |form| form.validate!(errors, prefixes+[dfn[:name]]) }
29
31
  end
30
32
  end
31
33
  end
data/lib/reform/form.rb CHANGED
@@ -1,11 +1,7 @@
1
- require "disposable/twin/schema"
2
-
3
1
  module Reform
4
2
  class Form < Contract
5
- representer_class.instance_eval do
6
- def default_inline_class
7
- Form
8
- end
3
+ def self.default_nested_class
4
+ Form
9
5
  end
10
6
 
11
7
  require "reform/form/validate"
@@ -13,45 +9,59 @@ module Reform
13
9
 
14
10
  require "reform/form/populator"
15
11
 
12
+ # called after populator: form.deserialize(params)
13
+ # as this only included in the typed pipeline, it's not applied for scalars.
14
+ Deserialize = ->(input, options) { input.deserialize(options[:fragment]) } # TODO: (result:, fragment:, **o) once we drop 2.0.
15
+
16
16
  module Property
17
17
  # Add macro logic, e.g. for :populator.
18
- # TODO: This will be re-structured once Declarative allows it.
19
18
  def property(name, options={}, &block)
20
- if deserializer = options[:deserializer] # this means someone is explicitly specifying :deserializer.
21
- options[:deserializer] = Representable::Cloneable::Hash[deserializer]
22
- end
23
-
24
19
  definition = super # let representable sort out inheriting of properties, and so on.
25
- definition.merge!(deserializer: Representable::Cloneable::Hash.new) unless definition[:deserializer] # always keep :deserializer per property.
20
+ definition.merge!(deserializer: {}) unless definition[:deserializer] # always keep :deserializer per property.
26
21
 
27
22
  deserializer_options = definition[:deserializer]
28
23
 
29
24
  # Populators
30
- # * they assign created data, no :setter (hence the name).
31
- # * they (ab)use :instance, this is why they need to return a twin form.
32
- # * they are only used in the deserializer.
33
- if populator = options.delete(:populate_if_empty)
34
- deserializer_options.merge!({instance: Populator::IfEmpty.new(populator)})
35
- deserializer_options.merge!({setter: nil})
36
- elsif populator = options.delete(:populator)
37
- deserializer_options.merge!({instance: Populator.new(populator)})
38
- deserializer_options.merge!({setter: nil})
25
+ internal_populator = Populator::Sync.new(nil)
26
+ if block = definition[:populate_if_empty]
27
+ internal_populator = Populator::IfEmpty.new(block)
28
+ end
29
+ if block = definition[:populator] # populator wins over populate_if_empty when :inherit
30
+ internal_populator = Populator.new(block)
31
+ end
32
+ definition.merge!(internal_populator: internal_populator) unless options[:internal_populator]
33
+ external_populator = Populator::External.new
34
+
35
+ # always compute a parse_pipeline for each property of the deserializer and inject it via :parse_pipeline.
36
+ # first, let representable compute the pipeline functions by invoking #parse_functions.
37
+ if definition[:nested]
38
+ parse_pipeline = ->(input, options) do
39
+ functions = options[:binding].send(:parse_functions)
40
+ pipeline = Representable::Pipeline[*functions] # Pipeline[StopOnExcluded, AssignName, ReadFragment, StopOnNotFound, OverwriteOnNil, Collect[#<Representable::Function::CreateObject:0xa6148ec>, #<Representable::Function::Decorate:0xa6148b0>, Deserialize], Set]
41
+
42
+ pipeline = Representable::Pipeline::Insert.(pipeline, external_populator, replace: Representable::CreateObject::Instance)
43
+ pipeline = Representable::Pipeline::Insert.(pipeline, Representable::Decorate, delete: true)
44
+ pipeline = Representable::Pipeline::Insert.(pipeline, Deserialize, replace: Representable::Deserialize)
45
+ pipeline = Representable::Pipeline::Insert.(pipeline, Representable::SetValue, delete: true) # FIXME: only diff to options without :populator
46
+ end
47
+ else
48
+ parse_pipeline = ->(input, options) do
49
+ functions = options[:binding].send(:parse_functions)
50
+ pipeline = Representable::Pipeline[*functions] # Pipeline[StopOnExcluded, AssignName, ReadFragment, StopOnNotFound, OverwriteOnNil, Collect[#<Representable::Function::CreateObject:0xa6148ec>, #<Representable::Function::Decorate:0xa6148b0>, Deserialize], Set]
51
+
52
+ # FIXME: this won't work with property :name, inherit: true (where there is a populator set already).
53
+ pipeline = Representable::Pipeline::Insert.(pipeline, external_populator, replace: Representable::SetValue) if definition[:populator] # FIXME: only diff to options without :populator
54
+ pipeline
55
+ end
39
56
  end
40
57
 
58
+ deserializer_options[:parse_pipeline] ||= parse_pipeline
41
59
 
42
- # TODO: shouldn't that go into validate?
43
- if proc = options.delete(:skip_if)
60
+ if proc = definition[:skip_if]
44
61
  proc = Reform::Form::Validate::Skip::AllBlank.new if proc == :all_blank
45
-
46
- deserializer_options.merge!(skip_parse: proc)
62
+ deserializer_options.merge!(skip_parse: proc) # TODO: same with skip_parse ==> External
47
63
  end
48
64
 
49
- # default:
50
- # add Sync populator to nested forms.
51
- # FIXME: this is, of course, ridiculous and needs a better structuring.
52
- if (deserializer_options == {} || deserializer_options.keys == [:skip_parse]) && definition[:twin] && !options[:inherit] # FIXME: hmm. not a fan of this: only add when no other option given?
53
- deserializer_options.merge!(instance: Populator::Sync.new(nil), setter: nil)
54
- end
55
65
 
56
66
  # per default, everything should be writeable for the deserializer (we're only writing on the form). however, allow turning it off.
57
67
  deserializer_options.merge!(writeable: true) unless deserializer_options.has_key?(:writeable)
@@ -76,5 +86,9 @@ module Reform
76
86
 
77
87
  require "reform/form/prepopulate"
78
88
  include Prepopulate
89
+
90
+ def skip!
91
+ Representable::Pipeline::Stop
92
+ end
79
93
  end
80
94
  end
@@ -28,16 +28,16 @@ module Reform::Form::ActiveModel
28
28
  end
29
29
 
30
30
  # DISCUSS: can we achieve that somehow via features in build_inline?
31
- def process_inline!(mod, definition)
32
- _name = definition.name
33
- mod.instance_eval do
34
- @_name = _name.singularize.camelize
35
- # this adds Form::name for AM::Validations and I18N.
36
- # i have a feeling that this is also needed for Rails autoloader, which is scary.
37
- # beside that, it is a nice way for debugging to find out which anonymous form class you're working on:
38
- # anonymous_nested_form.class.name
39
- def name
40
- @_name
31
+ def property(*)
32
+ super.tap do |dfn|
33
+ return dfn unless dfn[:nested]
34
+ _name = dfn[:name]
35
+ dfn[:nested].instance_eval do
36
+ @_name = _name.singularize.camelize
37
+ # this adds Form::name for AM::Validations and I18N.
38
+ def name
39
+ @_name
40
+ end
41
41
  end
42
42
  end
43
43
  end
@@ -13,7 +13,7 @@ module Reform::Form::ActiveModel
13
13
  # TODO: add that shit in Form#present, not by overriding ::property.
14
14
  def property(name, options={}, &block)
15
15
  super.tap do |definition|
16
- add_nested_attribute_compat(name) if definition[:twin] # TODO: fix that in Rails FB#1832 work.
16
+ add_nested_attribute_compat(name) if definition[:nested] # TODO: fix that in Rails FB#1832 work.
17
17
  end
18
18
  end
19
19
 
@@ -35,13 +35,14 @@ module Reform::Form::ActiveModel
35
35
 
36
36
  private
37
37
  def rename_nested_param_for!(params, dfn)
38
- nested_name = "#{dfn.name}_attributes"
38
+ name = dfn[:name]
39
+ nested_name = "#{name}_attributes"
39
40
  return unless params.has_key?(nested_name)
40
41
 
41
- value = params["#{dfn.name}_attributes"]
42
+ value = params["#{name}_attributes"]
42
43
  value = value.values if dfn[:collection]
43
44
 
44
- params[dfn.name] = value
45
+ params[name] = value
45
46
  end
46
47
  end
47
48
  end
@@ -7,7 +7,7 @@ class Reform::Form < Reform::Contract
7
7
  module ActiveModel::ModelReflections
8
8
  def self.included(base)
9
9
  base.extend ClassMethods
10
- base.register_feature self # makes it work in nested forms.
10
+ base.send :register_feature, self # makes it work in nested forms.
11
11
  end
12
12
 
13
13
  module ClassMethods
@@ -19,7 +19,7 @@ class Reform::Form < Reform::Contract
19
19
 
20
20
  # this is needed in simpleform to infer required fields.
21
21
  def validators_on(*args)
22
- validator.validators_on(*args)
22
+ validation_groups.collect { |k, group| group.instance_variable_get(:@validations).validators_on(*args) }.flatten
23
23
  end
24
24
  end
25
25
 
@@ -63,8 +63,8 @@ module Reform::Form::ActiveModel
63
63
  def self.from_representable_attrs(attrs)
64
64
  new.tap do |mapping|
65
65
  attrs.each do |dfn|
66
- from = dfn.name.to_sym
67
- to = [dfn[:on], (dfn[:private_name] || dfn.name)].compact.map(&:to_sym)
66
+ from = dfn[:name].to_sym
67
+ to = [dfn[:on], (dfn[:private_name] || dfn[:name])].compact.map(&:to_sym)
68
68
  mapping.add(from, to)
69
69
  end
70
70
  end
@@ -103,7 +103,7 @@ module Reform::Form::ActiveModel
103
103
  end
104
104
 
105
105
  def copy_validations_from(models)
106
- ValidationCopier.copy(self, Mapping.from_representable_attrs(representer_class.representable_attrs), models)
106
+ ValidationCopier.copy(self, Mapping.from_representable_attrs(definitions), models)
107
107
  end
108
108
 
109
109
  end