hungryform 0.0.4 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -1
  3. data/.rspec +0 -1
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +5 -0
  6. data/README.md +72 -43
  7. data/Rakefile +3 -4
  8. data/hungryform.gemspec +4 -4
  9. data/lib/hungryform/configuration.rb +31 -0
  10. data/lib/hungryform/elements/base/active_element.rb +44 -36
  11. data/lib/hungryform/elements/base/element.rb +40 -49
  12. data/lib/hungryform/elements/base/group.rb +74 -71
  13. data/lib/hungryform/elements/base/hashable.rb +32 -30
  14. data/lib/hungryform/elements/base/options_element.rb +28 -24
  15. data/lib/hungryform/elements/html.rb +1 -1
  16. data/lib/hungryform/elements/page.rb +4 -0
  17. data/lib/hungryform/elements/radio_group.rb +1 -1
  18. data/lib/hungryform/elements/select_field.rb +14 -18
  19. data/lib/hungryform/elements/{text_area_field.rb → text_area.rb} +1 -1
  20. data/lib/hungryform/elements.rb +9 -1
  21. data/lib/hungryform/exceptions.rb +3 -0
  22. data/lib/hungryform/form.rb +32 -2
  23. data/lib/hungryform/resolver.rb +14 -16
  24. data/lib/hungryform/version.rb +1 -1
  25. data/lib/hungryform.rb +22 -5
  26. data/spec/elements/group_spec.rb +10 -1
  27. data/spec/elements/html_spec.rb +11 -9
  28. data/spec/elements/page_spec.rb +10 -7
  29. data/spec/elements/radio_group_spec.rb +9 -15
  30. data/spec/elements/select_field_spec.rb +19 -33
  31. data/spec/elements/shared_examples/active_element.rb +52 -0
  32. data/spec/elements/shared_examples/element.rb +42 -0
  33. data/spec/elements/shared_examples/group.rb +31 -0
  34. data/spec/elements/shared_examples/options_element.rb +24 -0
  35. data/spec/elements/text_area_spec.rb +14 -0
  36. data/spec/elements/text_field_spec.rb +10 -3
  37. data/spec/form_spec.rb +68 -1
  38. data/spec/resolver_spec.rb +7 -7
  39. data/spec/spec_helper.rb +4 -2
  40. metadata +29 -40
  41. data/Gemfile.lock +0 -52
  42. data/spec/elements/text_area_field_spec.rb +0 -7
  43. data/spec/support/shared_active_element.rb +0 -65
  44. data/spec/support/shared_element.rb +0 -62
  45. data/spec/support/shared_group.rb +0 -42
  46. data/spec/support/shared_options_element.rb +0 -36
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 301fe1318d8aec9203be048d49946604a9c90826
4
- data.tar.gz: 58eed16ad2bf95ffd8453d6225c32e79234beaf1
3
+ metadata.gz: 366185c77f738aac57f059664729402272c35d18
4
+ data.tar.gz: 4368d143b24f7eec28af6ca428de93eebabbd6fd
5
5
  SHA512:
6
- metadata.gz: d4da2b5138ddbbad90956b0bd0fbbbfa885f7ae3d25518951629d8d98c46518d1e81f759f523222e52075c89e69312f6d9417ec5cdd2ff55c2f105c5ef624fb0
7
- data.tar.gz: 7a443c26c7fe85572cb9a15f70df473f59ccdca5f02aab2ed676ea49f98eebe01cbe428603ea0560ac39edeb73a4e2a7ac24ff82772ee69de471a31c5a7379ca
6
+ metadata.gz: 19bdd1d7bdad63873e2386fe74e0fe8efd184b7eb5d295acf79899093d57ee71a66bc7b36f380fa32b0555917a703ef0f5a6376df5f16df29065bee6d876420e
7
+ data.tar.gz: db49ba35e648b857964f43fb82569f270521c196d8153f02337aed5ee47fd9e819233bf5eec81464b9aa42cf64252a6b0aa89191a4d208ac40d5ec53d762b0c1
data/.gitignore CHANGED
@@ -1 +1,6 @@
1
- *.gem
1
+ *.gem
2
+ *.log
3
+
4
+ Gemfile.lock
5
+ gemfiles/*.lock
6
+ spec/app/tmp
data/.rspec CHANGED
@@ -1,2 +1 @@
1
- --format documentation
2
1
  --color
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.1.5
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ install:
2
+ - 'travis_retry bundle install'
3
+ language:
4
+ - ruby
5
+ script: 'bundle exec rspec spec'
data/README.md CHANGED
@@ -1,8 +1,6 @@
1
- # HungryForm
1
+ # HungryForm [![Build Status](https://travis-ci.org/andrba/hungryform.svg?branch=master)](https://travis-ci.org/andrba/hungryform) [![Code Climate](https://codeclimate.com/github/andrba/hungryform/badges/gpa.svg)](https://codeclimate.com/github/andrba/hungryform)
2
2
 
3
- [![Build Status](https://travis-ci.org/andrba/hungryform.svg?branch=master)](https://travis-ci.org/andrba/hungryform)
4
-
5
- HungryForm is a gem for managing multiple page forms. The main purpose of this gem is to give developers an easy DSL to build complex forms.
3
+ HungryForm is a gem for managing multiple page forms. The main purpose of this gem is to give developers an easy DSL to build complex forms.
6
4
 
7
5
  ## Usage
8
6
 
@@ -20,81 +18,112 @@ form = HungryForm::Form.new do
20
18
  text_field :occupation
21
19
 
22
20
  # Show this group only when the occupation field is not empty
23
- group :employment_history, dependency: '{"SET": "third_occupation"}' do
21
+ group :employment_history, dependency: { set: "third_occupation" } do
24
22
  html :before, value: "Employment history over the last 5 years"
25
23
  text_area :history, value: "Default value"
26
24
  end
27
25
  end
28
26
  end
29
- ```
30
-
31
- To assign values to the form elements pass them as a hash on form initialization. The params hash must consist of elements names and their values. Please note, that the elements names must contain the full path to the element, starting from the page name.
32
-
33
- ```ruby
34
- params = {
35
- "first_first_name" => "John",
36
- "first_last_name" => "Doe",
37
- "second_address" => "John's address",
38
- "third_occupation" => "Software engineer",
39
- "third_employment_history_history" => "John's employment hisotory"
40
- }
41
27
 
42
- form = HungryForm::Form.new :params => params do
43
- ...
28
+ if form.valid?
29
+ form.to_json
44
30
  end
45
-
46
31
  ```
32
+ ## Field Dependencies
47
33
 
48
- You can assign default value to a form element:
34
+ Each element of HungryForm, including pages and groups, can have a ```dependency``` parameter. This parameter must be a hash, containing a tree of basic operations. The dependency tree eventually resolves into to a boolean result. Within this tree you can use and combine the following operators, creating complex dependencies that can involve multiple elements:
49
35
 
50
36
  ```ruby
51
- text_field :email, value: "john.doe@yahoo.com"
52
- ```
53
- ## Dependencies
54
-
55
- Each element of HungryForm, including pages and groups, can have a dependency parameter. This parameter must be a json string with an expression, that resolves to a boolean result. Within this expression you can use and combine the following operators, creating complex dependencies that can involve multiple elements:
56
-
57
- ```json
58
37
  # val1 == val2
59
- {"EQ": ["val1", "val2"]}
38
+ { eq: ["val1", "val2"] }
60
39
 
61
40
  # val1 > val2
62
- {"GT": ["val1", "val2"]}
41
+ { gt: ["val1", "val2"] }
63
42
 
64
43
  # val1 < val2
65
- {"LT": ["val1", "val2"]}
44
+ { lt: ["val1", "val2"] }
66
45
 
67
46
  # val1 is not empty
68
- {"SET": "val1"}
47
+ { set: "val1" }
69
48
 
70
49
  # Get the opposite result of the expression
71
- {"NOT": {"EQ": ["1", "1"]}}
50
+ { not: { eq: [1, 1] } }
72
51
 
73
52
  # Check if all the expressions are true
74
- {"AND": [
75
- {"EQ": ["1", "1"]},
76
- {"EQ": ["2", "2"]}
77
- ]}
53
+ {
54
+ and: [
55
+ { eq: [1, 1] },
56
+ { eq: [2, 2] }
57
+ ]
58
+ }
78
59
 
79
60
  # Check if any of the expressions is true
80
- {"OR": [
81
- {"NOT": {"EQ": ["1", "1"]}},
82
- {"EQ": ["2", "2"]}
83
- ]}
61
+ {
62
+ or: [
63
+ { not: { eq: [1, 1] } },
64
+ { eq: [2, 2] }
65
+ ]
66
+ }
84
67
  ```
85
68
 
86
- If the dependency is resolved positively it makes the element visible. Otherwise the element will be hidden and not required. It is allowed to use element names or params keys as parameters inside expressions.
69
+ If the dependency is resolved positively it makes the element visible. Otherwise the element will be hidden with all its validation rules omited. It is allowed to use element names or params keys as parameters inside expressions.
87
70
 
88
71
  ```ruby
89
72
  HungryForm::Form.new do
90
73
  page :about do
91
74
  text_field :age
92
- text_field :favourite_alcohol, required: true, dependency: '{"GT": ["about_age", "18"]}'
75
+ text_field :favourite_alcohol, required: true, dependency: { gt: ["about_age", 18] }
93
76
  end
94
77
  end
95
78
 
96
79
  ```
97
80
 
81
+ ## Assigning values
82
+
83
+ To assign values to form fields pass them as a hash on form initialization. The params hash must consist of field names and their values. Please note, that the field names must contain the full path to the field, starting from the page name.
84
+
85
+ ```ruby
86
+ params = {
87
+ "first_first_name" => "John",
88
+ "first_last_name" => "Doe",
89
+ "second_address" => "John's address",
90
+ "third_occupation" => "Software engineer",
91
+ "third_employment_history_history" => "John's employment history"
92
+ }
93
+
94
+ form = HungryForm::Form.new :params => params do
95
+ ...
96
+ end
97
+
98
+ ```
99
+
100
+ Assign a default value to a form field:
101
+
102
+ ```ruby
103
+ text_field :email, value: "john.doe@yahoo.com"
104
+ ```
105
+
106
+ You can assign any attribute to the field and it will be included into the field attributes during rendering:
107
+
108
+ ```ruby
109
+ text_field :email, my_attribute: "attribute value"
110
+ ```
111
+
112
+ ## Configuration
113
+
114
+ To configure the gem use the configuration block:
115
+
116
+ ```ruby
117
+ HungryForm.configure do |config|
118
+ config.views_prefix = 'myform'
119
+ config.text_field maxlength: 100
120
+ end
121
+ ```
122
+
123
+ ```views_prefix```: Set this option in case you want to override the standard elements templates with your own ones. The prefix must match the folder name in your views folder where you keep the elements partials.
124
+
125
+ ```text_field``` (or any other element name): Assign an attribute to all elements of this type
126
+
98
127
  ## Validation
99
128
 
100
129
  Each active element of a form can be assigned with validation rules.
data/Rakefile CHANGED
@@ -1,4 +1,3 @@
1
- require "bundler/gem_tasks"
2
- require 'rspec/core/rake_task'
3
- task :default => :spec
4
- RSpec::Core::RakeTask.new
1
+ # encoding: utf-8
2
+
3
+ require "bundler/gem_tasks"
data/hungryform.gemspec CHANGED
@@ -19,9 +19,9 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.required_ruby_version = '>= 1.9.2'
21
21
 
22
- spec.add_development_dependency "bundler", "~> 1.6"
23
- spec.add_development_dependency "rake"
24
- spec.add_development_dependency "rspec", "~> 3.0"
25
- spec.add_development_dependency 'pry'
26
22
  spec.add_dependency "activesupport"
23
+
24
+ spec.add_development_dependency "bundler", ['>= 1.0.0']
25
+ spec.add_development_dependency "rake", ['>= 0']
26
+ spec.add_development_dependency "rspec", ['>= 3.0']
27
27
  end
@@ -0,0 +1,31 @@
1
+ module HungryForm
2
+ class Configuration
3
+ attr_accessor :views_prefix
4
+
5
+ def initialize
6
+ @views_prefix = 'hungryform'
7
+
8
+ init_element_default_attributes
9
+ end
10
+
11
+ private
12
+
13
+ def init_element_default_attributes
14
+ @elements_default_attributes = {}
15
+
16
+ HungryForm::Elements.all_classes.each do |klass|
17
+ klass_name = klass.to_s.underscore.to_sym
18
+ @elements_default_attributes[klass_name] = {}
19
+
20
+ # Assign a default attribute to an element
21
+ define_singleton_method klass_name do |attributes = {}|
22
+ if attributes.any?
23
+ @elements_default_attributes[klass_name].merge!(attributes)
24
+ end
25
+
26
+ @elements_default_attributes[klass_name]
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,52 +1,60 @@
1
1
  module HungryForm
2
- module Elements::Base
3
- # The ActiveElement class is used as a base class for all
4
- # form fields that can contain values and be validated
5
- class ActiveElement < Element
6
- attr_accessor :error, :value, :required
7
- alias_method :required?, :required
2
+ module Elements
3
+ module Base
4
+ # The ActiveElement class is used as a base class for all
5
+ # form fields that can contain values and be validated
6
+ class ActiveElement < Element
7
+ attr_accessor :error, :value, :required
8
+ alias_method :required?, :required
8
9
 
9
- hashable :required, :value, :error
10
+ hashable :required, :value, :error
10
11
 
11
- def initialize(name, parent, resolver, attributes = {}, &block)
12
- super
12
+ def initialize(name, parent, resolver, attributes = {}, &block)
13
+ super
13
14
 
14
- clear_error
15
+ clear_error
15
16
 
16
- # Leave only the attributes that are being methods of the HungryForm::Validator class
17
- @validation_rules = @attributes.select { |key, _| HungryForm::Validator.respond_to?(key) }
18
-
19
- if parent.visible?
20
- self.required = @attributes[:required] || false
21
- else
22
- self.required = false
23
- end
17
+ if parent.visible?
18
+ self.required = @attributes[:required] || false
19
+ else
20
+ self.required = false
21
+ end
24
22
 
25
- set_value
26
- end
23
+ # Leave only the attributes that are being methods of the HungryForm::Validator class
24
+ @validation_rules = @attributes.select { |key, _| HungryForm::Validator.singleton_class.instance_methods(false).include?(key) }
25
+ @attributes.delete_if { |key, _| @validation_rules.key?(key) }
27
26
 
28
- def valid?
29
- clear_error
30
- is_valid = true
31
- return true unless visible?
27
+ set_value
28
+ end
32
29
 
33
- @validation_rules.each do |key, rule|
34
- error = HungryForm::Validator.send(key, self, rule) || ''
35
- unless error.empty?
36
- is_valid = false
37
- break
30
+ def valid?
31
+ clear_error
32
+ is_valid = true
33
+ return true unless visible?
34
+
35
+ @validation_rules.each do |key, rule|
36
+ self.error = HungryForm::Validator.send(key, self, rule) || ''
37
+ unless error.empty?
38
+ self.error = "This field #{error}"
39
+ is_valid = false
40
+ break
41
+ end
38
42
  end
43
+
44
+ is_valid
39
45
  end
40
46
 
41
- is_valid
42
- end
47
+ def invalid?
48
+ !valid?
49
+ end
43
50
 
44
- def set_value
45
- self.value = resolver.params.key?(name) ? resolver.params[name] : @attributes[:value]
46
- end
51
+ def set_value
52
+ self.value = resolver.params[name] || attributes.delete(:value)
53
+ end
47
54
 
48
- def clear_error
49
- self.error = ''
55
+ def clear_error
56
+ self.error = ''
57
+ end
50
58
  end
51
59
  end
52
60
  end
@@ -1,57 +1,48 @@
1
1
  module HungryForm
2
- module Elements::Base
3
- # The Element class is used in every form element. It contains the attrs
4
- # and methods used by all form elements, such as name, visible, dependency etc
5
- class Element
6
- include HungryForm::Elements::Base::Hashable
7
- attr_accessor :name, :placeholders, :resolver, :visible, :label, :dependency
8
- alias_method :visible?, :visible
9
-
10
- hashable :visible, :dependency, :name, :label
11
-
12
- def initialize(name, parent, resolver, attributes = {})
13
- @attributes = attributes.dup
14
-
15
- @placeholders ||= {}
16
- @resolver = resolver
17
-
18
- self.dependency ||= @attributes[:dependency]
19
-
20
- # The element is visible if no visible parameter passed or
21
- # visible param equals true and the dependency is resolved positively
22
- self.visible = @attributes.key?(:visible) ? @attributes[:visible] : true
23
-
24
- if dependency
25
- json_dependency = ::JSON.parse(dependency)
26
- self.visible &&= resolver.resolve_dependency(json_dependency)
2
+ module Elements
3
+ module Base
4
+ # The Element class is used in every form element. It contains the attrs
5
+ # and methods used by all form elements, such as name, visible, dependency etc
6
+ class Element
7
+ include HungryForm::Elements::Base::Hashable
8
+ attr_accessor :name, :placeholders, :resolver, :visible, :label, :dependency, :attributes
9
+ alias_method :visible?, :visible
10
+
11
+ hashable :visible, :dependency, :name, :label
12
+
13
+ def initialize(name, parent, resolver, attributes = {})
14
+ @attributes = HungryForm.configuration.send(self.class.name.demodulize.underscore).dup
15
+ @attributes.merge!(attributes)
16
+
17
+ @placeholders ||= {}
18
+ @resolver = resolver
19
+
20
+ self.dependency ||= @attributes.delete(:dependency)
21
+
22
+ # The element is visible if no visible parameter passed or
23
+ # visible param equals true and the dependency is resolved positively
24
+ self.visible = @attributes.key?(:visible) ? @attributes.delete(:visible) : true
25
+
26
+ if dependency
27
+ self.visible &&= resolver.resolve_dependency(dependency)
28
+ end
29
+
30
+ # An element's name is prefixed with all parents names up to the page
31
+ self.name = resolver.get_value(name, self)
32
+ self.name = "#{parent.name}_#{name}" unless parent.nil?
33
+
34
+ # Label can be created from name if there is no label given
35
+ if @attributes[:label]
36
+ self.label = resolver.get_value(@attributes.delete(:label), self)
37
+ else
38
+ self.label = resolver.get_value(name, self).humanize
39
+ end
27
40
  end
28
41
 
29
- # An element's name is prefixed with all parents names up to the page
30
- self.name = resolver.get_value(name, self)
31
- self.name = "#{parent.name}_#{name}" unless parent.nil?
32
-
33
- # Label can be created from name if there is no label given
34
- if @attributes[:label]
35
- self.label = resolver.get_value(@attributes[:label], self)
36
- else
37
- self.label = resolver.get_value(name, self).humanize
42
+ def dependency_json
43
+ JSON.generate(dependency) if dependency
38
44
  end
39
45
  end
40
-
41
- def method_missing(method_name, *args, &block)
42
- # Check if an option exists
43
- if method_name.to_s[-1] == '?'
44
- return @attributes.key?(method_name.to_s[0..-2].to_sym)
45
- end
46
-
47
- # Return an attribute
48
- return @attributes[method_name] if @attributes.key?(method_name)
49
- super
50
- end
51
-
52
- def respond_to_missing?(method_name, include_private = false)
53
- @attributes.key?(method_name) || super
54
- end
55
46
  end
56
47
  end
57
48
  end
@@ -1,88 +1,91 @@
1
1
  module HungryForm
2
- module Elements::Base
3
- # A base group object is used to handle nested elements.
4
- # Nested element can be a regular BaseElement or BaseActiveElement,
5
- # as well as a BaseGroup element.
6
- #
7
- # The following sample has three BaseGroup elements (page, group and nested group)
8
- # that define a structure of a single form page
9
- #
10
- # page :about do
11
- # group :about_yourself do
12
- # html :about, value: "Tell us about yourself"
13
- # group :address do
14
- # text_field :street
15
- # text_field :city
16
- # end
17
- # group :contact do
18
- # text_field :phone
19
- # end
20
- # end
21
- # end
22
- class Group < Element
23
- attr_accessor :elements, :errors
24
-
25
- hashable :elements
26
-
27
- def initialize(name, parent, resolver, attributes = {}, &block)
28
- unless block_given?
29
- fail HungryFormException, 'No group structure block given'
30
- end
31
-
32
- super
33
-
34
- @elements = []
35
- @errors = {}
2
+ module Elements
3
+ module Base
4
+ # A base group object is used to handle nested elements.
5
+ # Nested element can be a regular BaseElement or BaseActiveElement,
6
+ # as well as a BaseGroup element.
7
+ #
8
+ # The following sample has three BaseGroup elements (page, group and nested group)
9
+ # that define a structure of a single form page
10
+ #
11
+ # page :about do
12
+ # group :about_yourself do
13
+ # html :about, value: "Tell us about yourself"
14
+ # group :address do
15
+ # text_field :street
16
+ # text_field :city
17
+ # end
18
+ # group :contact do
19
+ # text_field :phone
20
+ # end
21
+ # end
22
+ # end
23
+ class Group < Element
24
+ attr_accessor :elements, :errors
25
+
26
+ hashable :elements
27
+
28
+ def initialize(name, parent, resolver, attributes = {}, &block)
29
+ unless block_given?
30
+ fail HungryFormException, 'No group structure block given'
31
+ end
36
32
 
37
- instance_eval(&block)
38
- end
33
+ super
39
34
 
40
- # Validates an entire group. If a group consists of nested groups
41
- # they will be validated recursively
42
- def valid?
43
- errors.clear
44
- is_valid = true
35
+ @elements = []
36
+ @errors = {}
45
37
 
46
- elements.each do |el|
47
- next if el.valid?
38
+ instance_eval(&block)
39
+ end
48
40
 
49
- is_valid = false
50
- case el
51
- when BaseActiveElement
52
- errors[el.name] = el.error
53
- when BaseGroupObject
54
- errors.merge!(el.errors)
41
+ # Validates an entire group. If a group consists of nested groups
42
+ # they will be validated recursively
43
+ def valid?
44
+ errors.clear
45
+ is_valid = true
46
+ return true unless visible?
47
+
48
+ elements.each do |el|
49
+ next if !el.respond_to?(:valid?) || el.valid?
50
+
51
+ is_valid = false
52
+ case el
53
+ when Base::ActiveElement
54
+ errors[el.name] = el.error
55
+ when Base::Group
56
+ errors.merge!(el.errors)
57
+ end
55
58
  end
56
- end
57
59
 
58
- is_valid
59
- end
60
+ is_valid
61
+ end
60
62
 
61
- def invalid?
62
- !valid?
63
- end
63
+ def invalid?
64
+ !valid?
65
+ end
64
66
 
65
- def to_hash
66
- super.merge(elements: elements.map(&:to_hash))
67
- end
67
+ def to_hash
68
+ super.merge(elements: elements.map(&:to_hash))
69
+ end
68
70
 
69
- def method_missing(method_name, *args, &block)
70
- # Find a matching class
71
- klass = HungryForm::Elements.constants.find { |c| Class === HungryForm::Elements.const_get(c) && c.to_s.underscore.to_sym == method_name }
72
- return super if klass.nil?
71
+ def method_missing(method_name, *args, &block)
72
+ # Find a matching class
73
+ klass = HungryForm::Elements.find_class(method_name)
74
+ return super if klass.nil?
73
75
 
74
- # Create a new element based on a symbol provided and push it into the group elements array
75
- element = HungryForm::Elements.const_get(klass).send(:new, args[0], self, @resolver, *(args[1..-1]), &block)
76
- elements << element
76
+ # Create a new element based on a symbol provided and push it into the group elements array
77
+ element = HungryForm::Elements.const_get(klass).send(:new, args[0], self, @resolver, *(args[1..-1]), &block)
78
+ elements << element
77
79
 
78
- # Resolver keeps a hash of all elements of the form
79
- @resolver.elements[element.name] = element
80
+ # Resolver keeps a hash of all elements of the form
81
+ @resolver.elements[element.name] = element
80
82
 
81
- element
82
- end
83
+ element
84
+ end
83
85
 
84
- def respond_to_missing?(method_name, include_private = false)
85
- HungryForm::Elements.constants.any? { |c| Class === HungryForm::Elements.const_get(c) && c.to_s.underscore.to_sym == method_name } || super
86
+ def respond_to_missing?(method_name, include_private = false)
87
+ HungryForm::Elements.find_class(method_name) || super
88
+ end
86
89
  end
87
90
  end
88
91
  end