simple_form 3.0.1 → 3.1.0

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 (86) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +44 -27
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +204 -81
  5. data/lib/generators/simple_form/install_generator.rb +3 -3
  6. data/lib/generators/simple_form/templates/README +3 -4
  7. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +28 -7
  8. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +115 -24
  9. data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +86 -5
  10. data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +7 -2
  11. data/lib/simple_form/action_view_extensions/builder.rb +1 -0
  12. data/lib/simple_form/action_view_extensions/form_helper.rb +6 -2
  13. data/lib/simple_form/components/errors.rb +28 -2
  14. data/lib/simple_form/components/hints.rb +2 -2
  15. data/lib/simple_form/components/html5.rb +1 -1
  16. data/lib/simple_form/components/label_input.rb +20 -2
  17. data/lib/simple_form/components/labels.rb +10 -6
  18. data/lib/simple_form/components/maxlength.rb +1 -1
  19. data/lib/simple_form/components/min_max.rb +1 -1
  20. data/lib/simple_form/components/pattern.rb +1 -1
  21. data/lib/simple_form/components/placeholders.rb +2 -2
  22. data/lib/simple_form/components/readonly.rb +1 -1
  23. data/lib/simple_form/form_builder.rb +123 -73
  24. data/lib/simple_form/helpers.rb +5 -5
  25. data/lib/simple_form/inputs/base.rb +33 -11
  26. data/lib/simple_form/inputs/block_input.rb +1 -1
  27. data/lib/simple_form/inputs/boolean_input.rb +28 -15
  28. data/lib/simple_form/inputs/collection_input.rb +30 -9
  29. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +6 -11
  30. data/lib/simple_form/inputs/collection_select_input.rb +4 -2
  31. data/lib/simple_form/inputs/date_time_input.rb +12 -2
  32. data/lib/simple_form/inputs/file_input.rb +4 -2
  33. data/lib/simple_form/inputs/grouped_collection_select_input.rb +15 -3
  34. data/lib/simple_form/inputs/hidden_input.rb +4 -2
  35. data/lib/simple_form/inputs/numeric_input.rb +5 -4
  36. data/lib/simple_form/inputs/password_input.rb +4 -2
  37. data/lib/simple_form/inputs/priority_input.rb +4 -2
  38. data/lib/simple_form/inputs/range_input.rb +1 -1
  39. data/lib/simple_form/inputs/string_input.rb +4 -2
  40. data/lib/simple_form/inputs/text_input.rb +4 -2
  41. data/lib/simple_form/railtie.rb +7 -0
  42. data/lib/simple_form/tags.rb +6 -0
  43. data/lib/simple_form/version.rb +1 -1
  44. data/lib/simple_form/wrappers/builder.rb +6 -6
  45. data/lib/simple_form/wrappers/leaf.rb +28 -0
  46. data/lib/simple_form/wrappers/many.rb +6 -6
  47. data/lib/simple_form/wrappers/root.rb +1 -1
  48. data/lib/simple_form/wrappers/single.rb +5 -3
  49. data/lib/simple_form/wrappers.rb +1 -0
  50. data/lib/simple_form.rb +59 -8
  51. data/test/action_view_extensions/builder_test.rb +36 -36
  52. data/test/action_view_extensions/form_helper_test.rb +33 -14
  53. data/test/components/label_test.rb +37 -37
  54. data/test/form_builder/association_test.rb +52 -35
  55. data/test/form_builder/button_test.rb +10 -10
  56. data/test/form_builder/error_notification_test.rb +1 -1
  57. data/test/form_builder/error_test.rb +144 -24
  58. data/test/form_builder/general_test.rb +89 -64
  59. data/test/form_builder/hint_test.rb +18 -18
  60. data/test/form_builder/input_field_test.rb +80 -16
  61. data/test/form_builder/label_test.rb +45 -13
  62. data/test/form_builder/wrapper_test.rb +135 -19
  63. data/test/generators/simple_form_generator_test.rb +4 -4
  64. data/test/inputs/boolean_input_test.rb +62 -6
  65. data/test/inputs/collection_check_boxes_input_test.rb +85 -17
  66. data/test/inputs/collection_radio_buttons_input_test.rb +134 -36
  67. data/test/inputs/collection_select_input_test.rb +146 -41
  68. data/test/inputs/datetime_input_test.rb +117 -50
  69. data/test/inputs/disabled_test.rb +15 -15
  70. data/test/inputs/discovery_test.rb +56 -6
  71. data/test/inputs/file_input_test.rb +2 -2
  72. data/test/inputs/general_test.rb +20 -20
  73. data/test/inputs/grouped_collection_select_input_test.rb +44 -8
  74. data/test/inputs/hidden_input_test.rb +4 -4
  75. data/test/inputs/numeric_input_test.rb +43 -43
  76. data/test/inputs/priority_input_test.rb +13 -13
  77. data/test/inputs/readonly_test.rb +19 -19
  78. data/test/inputs/required_test.rb +13 -13
  79. data/test/inputs/string_input_test.rb +50 -30
  80. data/test/inputs/text_input_test.rb +7 -7
  81. data/test/simple_form_test.rb +8 -0
  82. data/test/support/discovery_inputs.rb +32 -2
  83. data/test/support/misc_helpers.rb +77 -5
  84. data/test/support/models.rb +60 -24
  85. data/test/test_helper.rb +7 -1
  86. metadata +22 -33
@@ -2,116 +2,136 @@
2
2
  require 'test_helper'
3
3
 
4
4
  class StringInputTest < ActionView::TestCase
5
- test 'input should map text field to string attribute' do
5
+ test 'input maps text field to string attribute' do
6
6
  with_input_for @user, :name, :string
7
- assert_select "input#user_name[type=text][name='user[name]'][value=New in SimpleForm!]"
7
+ assert_select "input#user_name[type=text][name='user[name]'][value='New in SimpleForm!']"
8
8
  end
9
9
 
10
- test 'input should generate a password field for password attributes' do
10
+ test 'input generates a password field for password attributes' do
11
11
  with_input_for @user, :password, :password
12
12
  assert_select "input#user_password.password[type=password][name='user[password]']"
13
13
  end
14
14
 
15
- test 'input should get maxlength from column definition for string attributes' do
15
+ test 'input gets maxlength from column definition for string attributes' do
16
16
  with_input_for @user, :name, :string
17
- assert_select 'input.string[maxlength=100]'
17
+ assert_select 'input.string[maxlength="100"]'
18
18
  end
19
19
 
20
- test 'input should not get maxlength from column without size definition for string attributes' do
20
+ test 'input does not get maxlength from column without size definition for string attributes' do
21
21
  with_input_for @user, :action, :string
22
22
  assert_no_select 'input.string[maxlength]'
23
23
  end
24
24
 
25
- test 'input should get maxlength from column definition for password attributes' do
25
+ test 'input gets maxlength from column definition for password attributes' do
26
26
  with_input_for @user, :password, :password
27
- assert_select 'input.password[type=password][maxlength=100]'
27
+ assert_select 'input.password[type=password][maxlength="100"]'
28
28
  end
29
29
 
30
- test 'input should infer maxlength column definition from validation when present' do
30
+ test 'input infers maxlength column definition from validation when present' do
31
31
  with_input_for @validating_user, :name, :string
32
- assert_select 'input.string[maxlength=25]'
32
+ assert_select 'input.string[maxlength="25"]'
33
33
  end
34
34
 
35
- test 'input should not get maxlength from validation when tokenizer present' do
35
+ test 'input does not get maxlength from validation when tokenizer present' do
36
36
  with_input_for @validating_user, :action, :string
37
37
  assert_no_select 'input.string[maxlength]'
38
38
  end
39
39
 
40
- test 'input should get maxlength from validation when :is option present' do
40
+ test 'input gets maxlength from validation when :is option present' do
41
41
  with_input_for @validating_user, :home_picture, :string
42
- assert_select 'input.string[maxlength=12]'
42
+ assert_select 'input.string[maxlength="12"]'
43
43
  end
44
44
 
45
- test 'input maxlength should be the column limit plus one to make room for decimal point' do
45
+ test 'input maxlength is the column limit plus one to make room for decimal point' do
46
46
  with_input_for @user, :credit_limit, :string
47
47
 
48
- assert_select "input.string[maxlength=16]"
48
+ assert_select 'input.string[maxlength="16"]'
49
49
  end
50
50
 
51
- test 'input should not generate placeholder by default' do
51
+ test 'input does not generate placeholder by default' do
52
52
  with_input_for @user, :name, :string
53
53
  assert_no_select 'input[placeholder]'
54
54
  end
55
55
 
56
- test 'input should accept the placeholder option' do
56
+ test 'input accepts the placeholder option' do
57
57
  with_input_for @user, :name, :string, placeholder: 'Put in some text'
58
- assert_select 'input.string[placeholder=Put in some text]'
58
+ assert_select 'input.string[placeholder="Put in some text"]'
59
59
  end
60
60
 
61
- test 'input should generate a password field for password attributes that accept placeholder' do
61
+ test 'input generates a password field for password attributes that accept placeholder' do
62
62
  with_input_for @user, :password, :password, placeholder: 'Password Confirmation'
63
- assert_select 'input[type=password].password[placeholder=Password Confirmation]#user_password'
63
+ assert_select 'input[type=password].password[placeholder="Password Confirmation"]#user_password'
64
64
  end
65
65
 
66
- test 'input should not infer pattern from attributes by default' do
66
+ test 'input does not infer pattern from attributes by default' do
67
67
  with_input_for @other_validating_user, :country, :string
68
68
  assert_no_select 'input[pattern="\w+"]'
69
69
  end
70
70
 
71
- test 'input should infer pattern from attributes' do
71
+ test 'input infers pattern from attributes' do
72
72
  with_input_for @other_validating_user, :country, :string, pattern: true
73
73
  assert_select 'input[pattern="\w+"]'
74
74
  end
75
75
 
76
- test 'input should infer pattern from attributes using proc' do
76
+ test 'input infers pattern from attributes using proc' do
77
77
  with_input_for @other_validating_user, :name, :string, pattern: true
78
78
  assert_select 'input[pattern="\w+"]'
79
79
  end
80
80
 
81
- test 'input should not infer pattern from attributes if root default is false' do
81
+ test 'input does not infer pattern from attributes if root default is false' do
82
82
  swap_wrapper do
83
83
  with_input_for @other_validating_user, :country, :string
84
84
  assert_no_select 'input[pattern="\w+"]'
85
85
  end
86
86
  end
87
87
 
88
- test 'input should use given pattern from attributes' do
88
+ test 'input uses given pattern from attributes' do
89
89
  with_input_for @other_validating_user, :country, :string, input_html: { pattern: "\\d+" }
90
90
  assert_select 'input[pattern="\d+"]'
91
91
  end
92
92
 
93
- test 'input should not use pattern if model has :without validation option' do
93
+ test 'input does not use pattern if model has :without validation option' do
94
94
  with_input_for @other_validating_user, :description, :string, pattern: true
95
95
  assert_no_select 'input[pattern="\d+"]'
96
96
  end
97
97
 
98
- test 'input should use i18n to translate placeholder text' do
98
+ test 'input uses i18n to translate placeholder text' do
99
99
  store_translations(:en, simple_form: { placeholders: { user: {
100
100
  name: 'Name goes here'
101
101
  } } }) do
102
102
  with_input_for @user, :name, :string
103
- assert_select 'input.string[placeholder=Name goes here]'
103
+ assert_select 'input.string[placeholder="Name goes here"]'
104
+ end
105
+ end
106
+
107
+ test 'input uses custom i18n scope to translate placeholder text' do
108
+ store_translations(:en, my_scope: { placeholders: { user: {
109
+ name: 'Name goes here'
110
+ } } }) do
111
+ swap SimpleForm, i18n_scope: :my_scope do
112
+ with_input_for @user, :name, :string
113
+ assert_select 'input.string[placeholder="Name goes here"]'
114
+ end
115
+ end
116
+ end
117
+
118
+ test 'input translates a key prefixed with _html and return the html markup' do
119
+ store_translations(:en, simple_form: { labels: { user: {
120
+ name_html: '<b>Name</b>'
121
+ } } }) do
122
+ with_input_for @user, :name, :string
123
+ assert_select 'label b', 'Name'
104
124
  end
105
125
  end
106
126
 
107
127
  [:email, :url, :search, :tel].each do |type|
108
- test "input should allow type #{type}" do
128
+ test "input allows type #{type}" do
109
129
  with_input_for @user, :name, type
110
130
  assert_select "input.string.#{type}"
111
131
  assert_select "input[type=#{type}]"
112
132
  end
113
133
 
114
- test "input should not allow type #{type} if HTML5 compatibility is disabled" do
134
+ test "input does not allow type #{type} if HTML5 compatibility is disabled" do
115
135
  swap_wrapper do
116
136
  with_input_for @user, :name, type
117
137
  assert_select "input[type=text]"
@@ -2,23 +2,23 @@
2
2
  require 'test_helper'
3
3
 
4
4
  class TextInputTest < ActionView::TestCase
5
- test 'input should generate a text area for text attributes' do
5
+ test 'input generates a text area for text attributes' do
6
6
  with_input_for @user, :description, :text
7
7
  assert_select 'textarea.text#user_description'
8
8
  end
9
9
 
10
- test 'input should generate a text area for text attributes that accept placeholder' do
10
+ test 'input generates a text area for text attributes that accept placeholder' do
11
11
  with_input_for @user, :description, :text, placeholder: 'Put in some text'
12
- assert_select 'textarea.text[placeholder=Put in some text]'
12
+ assert_select 'textarea.text[placeholder="Put in some text"]'
13
13
  end
14
14
 
15
- test 'input should get maxlength from column definition for text attributes' do
15
+ test 'input gets maxlength from column definition for text attributes' do
16
16
  with_input_for @user, :description, :text
17
- assert_select 'textarea.text[maxlength=200]'
17
+ assert_select 'textarea.text[maxlength="200"]'
18
18
  end
19
19
 
20
- test 'input should infer maxlength column definition from validation when present for text attributes' do
20
+ test 'input infers maxlength column definition from validation when present for text attributes' do
21
21
  with_input_for @validating_user, :description, :text
22
- assert_select 'textarea.text[maxlength=50]'
22
+ assert_select 'textarea.text[maxlength="50"]'
23
23
  end
24
24
  end
@@ -6,4 +6,12 @@ class SimpleFormTest < ActiveSupport::TestCase
6
6
  assert_equal SimpleForm, config
7
7
  end
8
8
  end
9
+
10
+ test 'setup block configure Simple Form' do
11
+ SimpleForm.setup do |config|
12
+ assert_equal SimpleForm, config
13
+ end
14
+
15
+ assert_equal true, SimpleForm.configured?
16
+ end
9
17
  end
@@ -1,16 +1,26 @@
1
1
  class StringInput < SimpleForm::Inputs::StringInput
2
- def input
2
+ def input(wrapper_options = nil)
3
3
  "<section>#{super}</section>".html_safe
4
4
  end
5
5
  end
6
6
 
7
7
  class NumericInput < SimpleForm::Inputs::NumericInput
8
- def input
8
+ def input(wrapper_options = nil)
9
9
  "<section>#{super}</section>".html_safe
10
10
  end
11
11
  end
12
12
 
13
13
  class CustomizedInput < SimpleForm::Inputs::StringInput
14
+ def input(wrapper_options = nil)
15
+ "<section>#{super}</section>".html_safe
16
+ end
17
+
18
+ def input_method
19
+ :text_field
20
+ end
21
+ end
22
+
23
+ class DeprecatedInput < SimpleForm::Inputs::StringInput
14
24
  def input
15
25
  "<section>#{super}</section>".html_safe
16
26
  end
@@ -25,3 +35,23 @@ class CollectionSelectInput < SimpleForm::Inputs::CollectionSelectInput
25
35
  super.push('chosen')
26
36
  end
27
37
  end
38
+
39
+ module CustomInputs
40
+ class CustomizedInput < SimpleForm::Inputs::StringInput
41
+ def input_html_classes
42
+ super.push('customized-namespace-custom-input')
43
+ end
44
+ end
45
+
46
+ class PasswordInput < SimpleForm::Inputs::PasswordInput
47
+ def input_html_classes
48
+ super.push('password-custom-input')
49
+ end
50
+ end
51
+
52
+ class NumericInput < SimpleForm::Inputs::PasswordInput
53
+ def input_html_classes
54
+ super.push('numeric-custom-input')
55
+ end
56
+ end
57
+ end
@@ -46,12 +46,12 @@ module MiscHelpers
46
46
  end
47
47
  end
48
48
 
49
- def swap_wrapper(name=:default, wrapper=self.custom_wrapper)
50
- old = SimpleForm.wrappers[name]
51
- SimpleForm.wrappers[name] = wrapper
49
+ def swap_wrapper(name = :default, wrapper = self.custom_wrapper)
50
+ old = SimpleForm.wrappers[name.to_s]
51
+ SimpleForm.wrappers[name.to_s] = wrapper
52
52
  yield
53
53
  ensure
54
- SimpleForm.wrappers[name] = old
54
+ SimpleForm.wrappers[name.to_s] = old
55
55
  end
56
56
 
57
57
  def custom_wrapper
@@ -68,6 +68,48 @@ module MiscHelpers
68
68
  end
69
69
  end
70
70
 
71
+ def custom_wrapper_with_wrapped_optional_component
72
+ SimpleForm.build tag: :section, class: "custom_wrapper" do |b|
73
+ b.wrapper tag: :div, class: 'no_output_wrapper' do |ba|
74
+ ba.optional :hint, wrap_with: { tag: :p, class: 'omg_hint' }
75
+ end
76
+ end
77
+ end
78
+
79
+ def custom_wrapper_with_unless_blank
80
+ SimpleForm.build tag: :section, class: "custom_wrapper" do |b|
81
+ b.wrapper tag: :div, class: 'no_output_wrapper', unless_blank: true do |ba|
82
+ ba.optional :hint, wrap_with: { tag: :p, class: 'omg_hint' }
83
+ end
84
+ end
85
+ end
86
+
87
+ def custom_wrapper_with_input_class
88
+ SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
89
+ b.use :label
90
+ b.use :input, class: 'inline-class'
91
+ end
92
+ end
93
+
94
+ def custom_wrapper_with_label_class
95
+ SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
96
+ b.use :label, class: 'inline-class'
97
+ b.use :input
98
+ end
99
+ end
100
+
101
+ def custom_wrapper_with_input_attributes
102
+ SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
103
+ b.use :input, data: { modal: true }
104
+ end
105
+ end
106
+
107
+ def custom_wrapper_with_label_input_class
108
+ SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
109
+ b.use :label_input, class: 'inline-class'
110
+ end
111
+ end
112
+
71
113
  def custom_wrapper_with_wrapped_input
72
114
  SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
73
115
  b.wrapper tag: :div, class: 'elem' do |component|
@@ -112,6 +154,36 @@ module MiscHelpers
112
154
  end
113
155
  end
114
156
 
157
+ def custom_wrapper_with_additional_attributes
158
+ SimpleForm.build tag: :div, class: 'custom_wrapper', html: { data: { wrapper: :test }, title: 'some title' } do |b|
159
+ b.use :label_input
160
+ end
161
+ end
162
+
163
+ def custom_wrapper_with_full_error
164
+ SimpleForm.build tag: :div, class: 'custom_wrapper' do |b|
165
+ b.use :full_error, wrap_with: { tag: :span, class: :error }
166
+ end
167
+ end
168
+
169
+ def custom_wrapper_with_label_text
170
+ SimpleForm.build :label_text => proc { |label, required| "**#{label}**" } do |b|
171
+ b.use :label_input
172
+ end
173
+ end
174
+
175
+ def custom_wrapper_with_custom_label_component
176
+ SimpleForm.build tag: :span, class: 'custom_wrapper' do |b|
177
+ b.use :label_text
178
+ end
179
+ end
180
+
181
+ def custom_wrapper_with_html5_components
182
+ SimpleForm.build tag: :span, class: 'custom_wrapper' do |b|
183
+ b.use :label_text
184
+ end
185
+ end
186
+
115
187
  def custom_form_for(object, *args, &block)
116
188
  simple_form_for(object, *args, { builder: CustomFormBuilder }, &block)
117
189
  end
@@ -142,7 +214,7 @@ module MiscHelpers
142
214
  end
143
215
  end
144
216
 
145
- def with_input_for(object, attribute_name, type, options={})
217
+ def with_input_for(object, attribute_name, type, options = {})
146
218
  with_concat_form_for(object) do |f|
147
219
  f.input(attribute_name, options.merge(as: type))
148
220
  end
@@ -1,4 +1,4 @@
1
- Association = Struct.new(:klass, :name, :macro, :options)
1
+ Association = Struct.new(:klass, :name, :macro, :scope, :options)
2
2
 
3
3
  Column = Struct.new(:name, :type, :limit) do
4
4
  # Returns +true+ if the column is either of type integer, float or decimal.
@@ -7,16 +7,36 @@ Column = Struct.new(:name, :type, :limit) do
7
7
  end
8
8
  end
9
9
 
10
- Relation = Struct.new(:all) do
10
+ Relation = Struct.new(:records) do
11
+ delegate :each, to: :records
12
+
11
13
  def where(conditions = nil)
12
- self.class.new conditions ? all.first : all
14
+ self.class.new conditions ? records.first : records
13
15
  end
14
16
 
15
17
  def order(conditions = nil)
16
- self.class.new conditions ? all.last : all
18
+ self.class.new conditions ? records.last : records
19
+ end
20
+
21
+ alias_method :to_a, :records
22
+ alias_method :to_ary, :records
23
+ end
24
+
25
+ Picture = Struct.new(:id, :name) do
26
+ extend ActiveModel::Naming
27
+ include ActiveModel::Conversion
28
+
29
+ def self.where(conditions = nil)
30
+ if conditions.is_a?(Hash) && conditions[:name]
31
+ all.to_a.last
32
+ else
33
+ all
34
+ end
17
35
  end
18
36
 
19
- alias_method :to_a, :all
37
+ def self.all
38
+ Relation.new((1..3).map { |i| new(i, "#{name} #{i}") })
39
+ end
20
40
  end
21
41
 
22
42
  Company = Struct.new(:id, :name) do
@@ -28,11 +48,11 @@ Company = Struct.new(:id, :name) do
28
48
  end
29
49
 
30
50
  def self._relation
31
- Relation.new(all)
51
+ all
32
52
  end
33
53
 
34
54
  def self.all
35
- (1..3).map { |i| new(i, "#{name} #{i}") }
55
+ Relation.new((1..3).map { |i| new(i, "#{name} #{i}") })
36
56
  end
37
57
 
38
58
  def persisted?
@@ -53,7 +73,8 @@ class User
53
73
  :delivery_time, :born_at, :special_company_id, :country, :tags, :tag_ids,
54
74
  :avatar, :home_picture, :email, :status, :residence_country, :phone_number,
55
75
  :post_count, :lock_version, :amount, :attempts, :action, :credit_card, :gender,
56
- :extra_special_company_id
76
+ :extra_special_company_id, :pictures, :picture_ids, :special_pictures,
77
+ :special_picture_ids, :uuid
57
78
 
58
79
  def self.build(extra_attributes = {})
59
80
  attributes = {
@@ -66,7 +87,7 @@ class User
66
87
  new attributes
67
88
  end
68
89
 
69
- def initialize(options={})
90
+ def initialize(options = {})
70
91
  @new_record = false
71
92
  options.each do |key, value|
72
93
  send("#{key}=", value)
@@ -104,11 +125,22 @@ class User
104
125
  when :attempts then :integer
105
126
  when :action then :string
106
127
  when :credit_card then :string
128
+ when :uuid then :uuid
107
129
  end
108
130
  Column.new(attribute, column_type, limit)
109
131
  end
110
132
 
111
- def self.human_attribute_name(attribute)
133
+ def has_attribute?(attribute)
134
+ case attribute.to_sym
135
+ when :name, :status, :password, :description, :age,
136
+ :credit_limit, :active, :born_at, :delivery_time,
137
+ :created_at, :updated_at, :lock_version, :home_picture,
138
+ :amount, :attempts, :action, :credit_card, :uuid then true
139
+ else false
140
+ end
141
+ end
142
+
143
+ def self.human_attribute_name(attribute, options = {})
112
144
  case attribute
113
145
  when 'name'
114
146
  'Super User Name!'
@@ -117,35 +149,39 @@ class User
117
149
  when 'company'
118
150
  'Company Human Name!'
119
151
  else
120
- attribute.humanize
152
+ attribute.to_s.humanize
121
153
  end
122
154
  end
123
155
 
124
156
  def self.reflect_on_association(association)
125
157
  case association
126
158
  when :company
127
- Association.new(Company, association, :belongs_to, {})
159
+ Association.new(Company, association, :belongs_to, nil, {})
128
160
  when :tags
129
- Association.new(Tag, association, :has_many, {})
161
+ Association.new(Tag, association, :has_many, nil, {})
130
162
  when :first_company
131
- Association.new(Company, association, :has_one, {})
163
+ Association.new(Company, association, :has_one, nil, {})
132
164
  when :special_company
133
- Association.new(Company, association, :belongs_to, { conditions: { id: 1 } })
165
+ Association.new(Company, association, :belongs_to, nil, { conditions: { id: 1 } })
134
166
  when :extra_special_company
135
- Association.new(Company, association, :belongs_to, { conditions: proc { { id: 1 } } })
167
+ Association.new(Company, association, :belongs_to, nil, { conditions: proc { { id: self.id } } })
168
+ when :pictures
169
+ Association.new(Picture, association, :has_many, nil, {})
170
+ when :special_pictures
171
+ Association.new(Picture, association, :has_many, proc { where(name: self.name) }, {})
136
172
  end
137
173
  end
138
174
 
139
175
  def errors
140
176
  @errors ||= begin
141
- hash = Hash.new { |h,k| h[k] = [] }
142
- hash.merge!(
143
- name: ["can't be blank"],
144
- description: ["must be longer than 15 characters"],
145
- age: ["is not a number", "must be greater than 18"],
146
- company: ["company must be present"],
147
- company_id: ["must be valid"]
148
- )
177
+ errors = ActiveModel::Errors.new(self)
178
+ errors.add(:name, "cannot be blank")
179
+ errors.add(:description, 'must be longer than 15 characters')
180
+ errors.add(:age, 'is not a number')
181
+ errors.add(:age, 'must be greater than 18')
182
+ errors.add(:company, 'company must be present')
183
+ errors.add(:company_id, 'must be valid')
184
+ errors
149
185
  end
150
186
  end
151
187
 
data/test/test_helper.rb CHANGED
@@ -5,6 +5,8 @@ require 'minitest/autorun'
5
5
  require 'active_model'
6
6
  require 'action_controller'
7
7
  require 'action_view'
8
+ ActionView::RoutingUrlFor.send(:include, ActionDispatch::Routing::UrlFor)
9
+
8
10
  require 'action_view/template'
9
11
 
10
12
  require 'action_view/test_case'
@@ -28,7 +30,11 @@ I18n.default_locale = :en
28
30
 
29
31
  require 'country_select'
30
32
 
31
- ActionDispatch::Assertions::NO_STRIP << "label"
33
+ if defined?(HTMLSelector::NO_STRIP)
34
+ HTMLSelector::NO_STRIP << "label"
35
+ else
36
+ ActionDispatch::Assertions::NO_STRIP << "label"
37
+ end
32
38
 
33
39
  class ActionView::TestCase
34
40
  include MiscHelpers