simple_form 3.0.4 → 3.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.
Potentially problematic release.
This version of simple_form might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +32 -43
- data/MIT-LICENSE +1 -1
- data/README.md +146 -71
- data/lib/generators/simple_form/install_generator.rb +2 -2
- data/lib/generators/simple_form/templates/README +3 -4
- data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +19 -3
- data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +83 -22
- data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +1 -1
- data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +7 -2
- data/lib/simple_form.rb +38 -6
- data/lib/simple_form/action_view_extensions/form_helper.rb +1 -1
- data/lib/simple_form/components/errors.rb +27 -5
- data/lib/simple_form/components/hints.rb +2 -2
- data/lib/simple_form/components/html5.rb +1 -1
- data/lib/simple_form/components/label_input.rb +20 -2
- data/lib/simple_form/components/labels.rb +9 -5
- data/lib/simple_form/components/maxlength.rb +1 -1
- data/lib/simple_form/components/min_max.rb +1 -1
- data/lib/simple_form/components/pattern.rb +1 -1
- data/lib/simple_form/components/placeholders.rb +2 -2
- data/lib/simple_form/components/readonly.rb +1 -1
- data/lib/simple_form/form_builder.rb +92 -59
- data/lib/simple_form/helpers.rb +5 -5
- data/lib/simple_form/inputs/base.rb +34 -12
- data/lib/simple_form/inputs/block_input.rb +1 -1
- data/lib/simple_form/inputs/boolean_input.rb +23 -13
- data/lib/simple_form/inputs/collection_input.rb +32 -9
- data/lib/simple_form/inputs/collection_radio_buttons_input.rb +6 -11
- data/lib/simple_form/inputs/collection_select_input.rb +4 -2
- data/lib/simple_form/inputs/date_time_input.rb +12 -2
- data/lib/simple_form/inputs/file_input.rb +4 -2
- data/lib/simple_form/inputs/grouped_collection_select_input.rb +15 -3
- data/lib/simple_form/inputs/hidden_input.rb +4 -2
- data/lib/simple_form/inputs/numeric_input.rb +5 -4
- data/lib/simple_form/inputs/password_input.rb +4 -2
- data/lib/simple_form/inputs/priority_input.rb +4 -2
- data/lib/simple_form/inputs/range_input.rb +1 -1
- data/lib/simple_form/inputs/string_input.rb +4 -2
- data/lib/simple_form/inputs/text_input.rb +4 -2
- data/lib/simple_form/railtie.rb +7 -0
- data/lib/simple_form/tags.rb +7 -0
- data/lib/simple_form/version.rb +1 -1
- data/lib/simple_form/wrappers.rb +1 -0
- data/lib/simple_form/wrappers/builder.rb +5 -5
- data/lib/simple_form/wrappers/leaf.rb +28 -0
- data/lib/simple_form/wrappers/many.rb +5 -6
- data/lib/simple_form/wrappers/root.rb +1 -1
- data/lib/simple_form/wrappers/single.rb +5 -3
- data/test/action_view_extensions/builder_test.rb +2 -2
- data/test/components/label_test.rb +1 -1
- data/test/form_builder/association_test.rb +17 -0
- data/test/form_builder/error_notification_test.rb +1 -1
- data/test/form_builder/error_test.rb +51 -32
- data/test/form_builder/general_test.rb +2 -2
- data/test/form_builder/input_field_test.rb +21 -37
- data/test/form_builder/label_test.rb +24 -1
- data/test/form_builder/wrapper_test.rb +67 -0
- data/test/generators/simple_form_generator_test.rb +2 -2
- data/test/inputs/boolean_input_test.rb +50 -2
- data/test/inputs/collection_check_boxes_input_test.rb +40 -11
- data/test/inputs/collection_radio_buttons_input_test.rb +76 -17
- data/test/inputs/collection_select_input_test.rb +108 -3
- data/test/inputs/datetime_input_test.rb +105 -38
- data/test/inputs/discovery_test.rb +12 -1
- data/test/inputs/grouped_collection_select_input_test.rb +36 -0
- data/test/inputs/string_input_test.rb +20 -0
- data/test/simple_form_test.rb +8 -0
- data/test/support/discovery_inputs.rb +12 -2
- data/test/support/misc_helpers.rb +46 -8
- data/test/support/models.rb +49 -24
- metadata +7 -7
@@ -1,18 +1,69 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
require 'test_helper'
|
3
3
|
|
4
|
-
# Tests for
|
5
|
-
class
|
6
|
-
|
7
|
-
|
4
|
+
# Tests for datetime, date and time inputs when HTML5 compatibility is enabled in the wrapper.
|
5
|
+
class DateTimeInputWithHtml5Test < ActionView::TestCase
|
6
|
+
test 'input should generate a datetime input for datetime attributes if HTML5 compatibility is explicitly enbled' do
|
7
|
+
with_input_for @user, :created_at, :datetime, html5: true
|
8
|
+
|
9
|
+
assert_select 'input[type="datetime"]'
|
10
|
+
end
|
11
|
+
|
12
|
+
test 'input should generate a datetime select for datetime attributes' do
|
8
13
|
with_input_for @user, :created_at, :datetime
|
9
|
-
|
10
|
-
|
14
|
+
|
15
|
+
assert_select 'select.datetime'
|
16
|
+
end
|
17
|
+
|
18
|
+
test 'input should generate a date input for date attributes if HTML5 compatibility is explicitly enbled' do
|
19
|
+
with_input_for @user, :born_at, :date, html5: true
|
20
|
+
|
21
|
+
assert_select 'input[type="date"]'
|
22
|
+
end
|
23
|
+
|
24
|
+
test 'input should generate a date select for date attributes' do
|
25
|
+
with_input_for @user, :born_at, :date
|
26
|
+
|
27
|
+
assert_select 'select.date'
|
28
|
+
end
|
29
|
+
|
30
|
+
test 'input should generate a time input for time attributes if HTML5 compatibility is explicitly enbled' do
|
31
|
+
with_input_for @user, :delivery_time, :time, html5: true
|
32
|
+
|
33
|
+
assert_select 'input[type="time"]'
|
34
|
+
end
|
35
|
+
|
36
|
+
test 'input should generate a time select for time attributes' do
|
37
|
+
with_input_for @user, :delivery_time, :time
|
38
|
+
|
39
|
+
assert_select 'select.time'
|
40
|
+
end
|
41
|
+
|
42
|
+
test 'input should generate required html attribute' do
|
43
|
+
with_input_for @user, :delivery_time, :time, required: true, html5: true
|
44
|
+
assert_select 'input.required'
|
45
|
+
assert_select 'input[required]'
|
46
|
+
end
|
47
|
+
|
48
|
+
test 'input should have an aria-required html attribute' do
|
49
|
+
with_input_for @user, :delivery_time, :time, required: true, html5: true
|
50
|
+
assert_select 'input[aria-required=true]'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Tests for datetime, date and time inputs when HTML5 compatibility is enabled in the wrapper.
|
55
|
+
class DateTimeInputWithoutHtml5Test < ActionView::TestCase
|
56
|
+
test 'input should generate a datetime select by default for datetime attributes' do
|
57
|
+
swap_wrapper do
|
58
|
+
with_input_for @user, :created_at, :datetime
|
59
|
+
1.upto(5) do |i|
|
60
|
+
assert_select "form select.datetime#user_created_at_#{i}i"
|
61
|
+
end
|
11
62
|
end
|
12
63
|
end
|
13
64
|
|
14
65
|
test 'input should be able to pass options to datetime select' do
|
15
|
-
with_input_for @user, :created_at, :datetime,
|
66
|
+
with_input_for @user, :created_at, :datetime, html5: false,
|
16
67
|
disabled: true, prompt: { year: 'ano', month: 'mês', day: 'dia' }
|
17
68
|
|
18
69
|
assert_select 'select.datetime[disabled=disabled]'
|
@@ -21,16 +72,26 @@ class DateTimeInputTest < ActionView::TestCase
|
|
21
72
|
assert_select 'select.datetime option', 'dia'
|
22
73
|
end
|
23
74
|
|
75
|
+
test 'input should generate a datetime input for datetime attributes if HTML5 compatibility is explicitly enabled' do
|
76
|
+
swap_wrapper do
|
77
|
+
with_input_for @user, :created_at, :datetime, html5: true
|
78
|
+
|
79
|
+
assert_select 'input[type="datetime"]'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
24
83
|
test 'input should generate a date select for date attributes' do
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
84
|
+
swap_wrapper do
|
85
|
+
with_input_for @user, :born_at, :date
|
86
|
+
assert_select 'select.date#user_born_at_1i'
|
87
|
+
assert_select 'select.date#user_born_at_2i'
|
88
|
+
assert_select 'select.date#user_born_at_3i'
|
89
|
+
assert_no_select 'select.date#user_born_at_4i'
|
90
|
+
end
|
30
91
|
end
|
31
92
|
|
32
93
|
test 'input should be able to pass options to date select' do
|
33
|
-
with_input_for @user, :born_at, :date, as: :date,
|
94
|
+
with_input_for @user, :born_at, :date, as: :date, html5: false,
|
34
95
|
disabled: true, prompt: { year: 'ano', month: 'mês', day: 'dia' }
|
35
96
|
|
36
97
|
assert_select 'select.date[disabled=disabled]'
|
@@ -40,21 +101,31 @@ class DateTimeInputTest < ActionView::TestCase
|
|
40
101
|
end
|
41
102
|
|
42
103
|
test 'input should be able to pass :default to date select' do
|
43
|
-
with_input_for @user, :born_at, :date, default: Date.today
|
104
|
+
with_input_for @user, :born_at, :date, default: Date.today, html5: false
|
44
105
|
assert_select "select.date option[value=#{Date.today.year}][selected=selected]"
|
45
106
|
end
|
46
107
|
|
108
|
+
test 'input should generate a date input for date attributes if HTML5 compatibility is explicitly enabled' do
|
109
|
+
swap_wrapper do
|
110
|
+
with_input_for @user, :born_at, :date, html5: true
|
111
|
+
|
112
|
+
assert_select 'input[type="date"]'
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
47
116
|
test 'input should generate a time select for time attributes' do
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
117
|
+
swap_wrapper do
|
118
|
+
with_input_for @user, :delivery_time, :time
|
119
|
+
assert_select 'input[type=hidden]#user_delivery_time_1i'
|
120
|
+
assert_select 'input[type=hidden]#user_delivery_time_2i'
|
121
|
+
assert_select 'input[type=hidden]#user_delivery_time_3i'
|
122
|
+
assert_select 'select.time#user_delivery_time_4i'
|
123
|
+
assert_select 'select.time#user_delivery_time_5i'
|
124
|
+
end
|
54
125
|
end
|
55
126
|
|
56
127
|
test 'input should be able to pass options to time select' do
|
57
|
-
with_input_for @user, :delivery_time, :time, required: true,
|
128
|
+
with_input_for @user, :delivery_time, :time, required: true, html5: false,
|
58
129
|
disabled: true, prompt: { hour: 'hora', minute: 'minuto' }
|
59
130
|
|
60
131
|
assert_select 'select.time[disabled=disabled]'
|
@@ -62,44 +133,40 @@ class DateTimeInputTest < ActionView::TestCase
|
|
62
133
|
assert_select 'select.time option', 'minuto'
|
63
134
|
end
|
64
135
|
|
136
|
+
test 'input should generate a time input for time attributes if HTML5 compatibility is explicitly enabled' do
|
137
|
+
swap_wrapper do
|
138
|
+
with_input_for @user, :delivery_time, :time, html5: true
|
139
|
+
|
140
|
+
assert_select 'input[type="time"]'
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
65
144
|
test 'label should use i18n to get target for date input type' do
|
66
145
|
store_translations(:en, date: { order: ['month', 'day', 'year'] }) do
|
67
|
-
with_input_for :project, :created_at, :date
|
146
|
+
with_input_for :project, :created_at, :date, html5: false
|
68
147
|
assert_select 'label[for=project_created_at_2i]'
|
69
148
|
end
|
70
149
|
end
|
71
150
|
|
72
151
|
test 'label should use i18n to get target for datetime input type' do
|
73
152
|
store_translations(:en, date: { order: ['month', 'day', 'year'] }) do
|
74
|
-
with_input_for :project, :created_at, :datetime
|
153
|
+
with_input_for :project, :created_at, :datetime, html5: false
|
75
154
|
assert_select 'label[for=project_created_at_2i]'
|
76
155
|
end
|
77
156
|
end
|
78
157
|
|
79
158
|
test 'label should use order to get target when date input type' do
|
80
|
-
with_input_for :project, :created_at, :date, order: ['month', 'year', 'day']
|
159
|
+
with_input_for :project, :created_at, :date, order: ['month', 'year', 'day'], html5: false
|
81
160
|
assert_select 'label[for=project_created_at_2i]'
|
82
161
|
end
|
83
162
|
|
84
163
|
test 'label should use order to get target when datetime input type' do
|
85
|
-
with_input_for :project, :created_at, :datetime, order: ['month', 'year', 'day']
|
164
|
+
with_input_for :project, :created_at, :datetime, order: ['month', 'year', 'day'], html5: false
|
86
165
|
assert_select 'label[for=project_created_at_2i]'
|
87
166
|
end
|
88
167
|
|
89
168
|
test 'label should point to first option when time input type' do
|
90
|
-
with_input_for :project, :created_at, :time
|
169
|
+
with_input_for :project, :created_at, :time, html5: false
|
91
170
|
assert_select 'label[for=project_created_at_4i]'
|
92
171
|
end
|
93
|
-
|
94
|
-
test 'date time input should generate required html attribute' do
|
95
|
-
with_input_for @user, :delivery_time, :time, required: true
|
96
|
-
assert_select 'select.required'
|
97
|
-
assert_select 'select[required]'
|
98
|
-
end
|
99
|
-
|
100
|
-
test 'date time input has an aria-required html attribute' do
|
101
|
-
with_input_for @user, :delivery_time, :time, required: true
|
102
|
-
assert_select 'select.required'
|
103
|
-
assert_select 'select[aria-required=true]'
|
104
|
-
end
|
105
172
|
end
|
@@ -2,7 +2,7 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class DiscoveryTest < ActionView::TestCase
|
4
4
|
# Setup new inputs and remove them after the test.
|
5
|
-
def discovery(value=false)
|
5
|
+
def discovery(value = false)
|
6
6
|
swap SimpleForm, cache_discovery: value do
|
7
7
|
begin
|
8
8
|
load "support/discovery_inputs.rb"
|
@@ -12,6 +12,7 @@ class DiscoveryTest < ActionView::TestCase
|
|
12
12
|
Object.send :remove_const, :StringInput
|
13
13
|
Object.send :remove_const, :NumericInput
|
14
14
|
Object.send :remove_const, :CustomizedInput
|
15
|
+
Object.send :remove_const, :DeprecatedInput
|
15
16
|
Object.send :remove_const, :CollectionSelectInput
|
16
17
|
end
|
17
18
|
end
|
@@ -66,4 +67,14 @@ class DiscoveryTest < ActionView::TestCase
|
|
66
67
|
assert_select 'form select#user_active.select.chosen'
|
67
68
|
end
|
68
69
|
end
|
70
|
+
|
71
|
+
test 'inputs method without wrapper_options are deprecated' do
|
72
|
+
discovery do
|
73
|
+
assert_deprecated do
|
74
|
+
with_form_for @user, :name, as: :deprecated
|
75
|
+
end
|
76
|
+
|
77
|
+
assert_select 'form section input#user_name.string'
|
78
|
+
end
|
79
|
+
end
|
69
80
|
end
|
@@ -79,6 +79,42 @@ class GroupedCollectionSelectInputTest < ActionView::TestCase
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
+
test 'grouped collection finds default label methods on the group objects' do
|
83
|
+
option_list = ['Jose', 'Carlos']
|
84
|
+
|
85
|
+
GroupedClass = Struct.new(:to_label, :options)
|
86
|
+
group = GroupedClass.new("Authors", option_list)
|
87
|
+
|
88
|
+
with_input_for @user, :tag_ids, :grouped_select,
|
89
|
+
collection: [group],
|
90
|
+
group_method: :options
|
91
|
+
|
92
|
+
assert_select 'select.grouped_select#user_tag_ids' do
|
93
|
+
assert_select 'optgroup[label=Authors]' do
|
94
|
+
assert_select 'option', 'Jose'
|
95
|
+
assert_select 'option', 'Carlos'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
test 'grouped collections finds the default label method from the first non-empty object' do
|
101
|
+
Agent = Struct.new(:id, :name)
|
102
|
+
agents = [["First", []], ["Second", [Agent.new(7, 'Bond'), Agent.new(47, 'Hitman')]]]
|
103
|
+
|
104
|
+
with_input_for @user, :tag_ids, :grouped_select,
|
105
|
+
collection: agents,
|
106
|
+
group_label_method: :first,
|
107
|
+
group_method: :last,
|
108
|
+
include_blank: false
|
109
|
+
|
110
|
+
assert_select 'select.grouped_select#user_tag_ids' do
|
111
|
+
assert_select 'optgroup[label=Second]' do
|
112
|
+
assert_select 'option[value=7]', 'Bond'
|
113
|
+
assert_select 'option[value=47]', 'Hitman'
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
82
118
|
test 'grouped collection accepts label and value methods options' do
|
83
119
|
with_input_for @user, :tag_ids, :grouped_select,
|
84
120
|
collection: { 'Authors' => ['Jose', 'Carlos'] },
|
@@ -104,6 +104,26 @@ class StringInputTest < ActionView::TestCase
|
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
|
+
test 'input should use 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 should translate 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'
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
107
127
|
[:email, :url, :search, :tel].each do |type|
|
108
128
|
test "input should allow type #{type}" do
|
109
129
|
with_input_for @user, :name, type
|
data/test/simple_form_test.rb
CHANGED
@@ -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
|
@@ -46,12 +46,12 @@ module MiscHelpers
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
def swap_wrapper(name
|
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,32 @@ module MiscHelpers
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
+
def custom_wrapper_with_input_class
|
72
|
+
SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
|
73
|
+
b.use :label
|
74
|
+
b.use :input, class: 'inline-class'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def custom_wrapper_with_label_class
|
79
|
+
SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
|
80
|
+
b.use :label, class: 'inline-class'
|
81
|
+
b.use :input
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def custom_wrapper_with_input_attributes
|
86
|
+
SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
|
87
|
+
b.use :input, data: { modal: true }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def custom_wrapper_with_label_input_class
|
92
|
+
SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
|
93
|
+
b.use :label_input, class: 'inline-class'
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
71
97
|
def custom_wrapper_with_wrapped_input
|
72
98
|
SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
|
73
99
|
b.wrapper tag: :div, class: 'elem' do |component|
|
@@ -112,9 +138,21 @@ module MiscHelpers
|
|
112
138
|
end
|
113
139
|
end
|
114
140
|
|
115
|
-
def
|
116
|
-
SimpleForm.build tag: :
|
117
|
-
b.use :
|
141
|
+
def custom_wrapper_with_additional_attributes
|
142
|
+
SimpleForm.build tag: :div, class: 'custom_wrapper', html: { data: { wrapper: :test }, title: 'some title' } do |b|
|
143
|
+
b.use :label_input
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def custom_wrapper_with_full_error
|
148
|
+
SimpleForm.build tag: :div, class: 'custom_wrapper' do |b|
|
149
|
+
b.use :full_error, wrap_with: { tag: :span, class: :error }
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def custom_wrapper_with_label_text
|
154
|
+
SimpleForm.build :label_text => proc { |label, required| "**#{label}**" } do |b|
|
155
|
+
b.use :label_input
|
118
156
|
end
|
119
157
|
end
|
120
158
|
|
@@ -148,7 +186,7 @@ module MiscHelpers
|
|
148
186
|
end
|
149
187
|
end
|
150
188
|
|
151
|
-
def with_input_for(object, attribute_name, type, options={})
|
189
|
+
def with_input_for(object, attribute_name, type, options = {})
|
152
190
|
with_concat_form_for(object) do |f|
|
153
191
|
f.input(attribute_name, options.merge(as: type))
|
154
192
|
end
|
data/test/support/models.rb
CHANGED
@@ -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(:
|
10
|
+
Relation = Struct.new(:records) do
|
11
|
+
delegate :each, to: :records
|
12
|
+
|
11
13
|
def where(conditions = nil)
|
12
|
-
self.class.new conditions ?
|
14
|
+
self.class.new conditions ? records.first : records
|
13
15
|
end
|
14
16
|
|
15
17
|
def order(conditions = nil)
|
16
|
-
self.class.new conditions ?
|
18
|
+
self.class.new conditions ? records.last : records
|
17
19
|
end
|
18
20
|
|
19
|
-
alias_method :to_a,
|
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
|
35
|
+
end
|
36
|
+
|
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
|
-
|
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
|
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)
|
@@ -108,7 +129,7 @@ class User
|
|
108
129
|
Column.new(attribute, column_type, limit)
|
109
130
|
end
|
110
131
|
|
111
|
-
def self.human_attribute_name(attribute)
|
132
|
+
def self.human_attribute_name(attribute, options = {})
|
112
133
|
case attribute
|
113
134
|
when 'name'
|
114
135
|
'Super User Name!'
|
@@ -117,35 +138,39 @@ class User
|
|
117
138
|
when 'company'
|
118
139
|
'Company Human Name!'
|
119
140
|
else
|
120
|
-
attribute.humanize
|
141
|
+
attribute.to_s.humanize
|
121
142
|
end
|
122
143
|
end
|
123
144
|
|
124
145
|
def self.reflect_on_association(association)
|
125
146
|
case association
|
126
147
|
when :company
|
127
|
-
Association.new(Company, association, :belongs_to, {})
|
148
|
+
Association.new(Company, association, :belongs_to, nil, {})
|
128
149
|
when :tags
|
129
|
-
Association.new(Tag, association, :has_many, {})
|
150
|
+
Association.new(Tag, association, :has_many, nil, {})
|
130
151
|
when :first_company
|
131
|
-
Association.new(Company, association, :has_one, {})
|
152
|
+
Association.new(Company, association, :has_one, nil, {})
|
132
153
|
when :special_company
|
133
|
-
Association.new(Company, association, :belongs_to, { conditions: { id: 1 } })
|
154
|
+
Association.new(Company, association, :belongs_to, nil, { conditions: { id: 1 } })
|
134
155
|
when :extra_special_company
|
135
|
-
Association.new(Company, association, :belongs_to, { conditions: proc { { id:
|
156
|
+
Association.new(Company, association, :belongs_to, nil, { conditions: proc { { id: self.id } } })
|
157
|
+
when :pictures
|
158
|
+
Association.new(Picture, association, :has_many, nil, {})
|
159
|
+
when :special_pictures
|
160
|
+
Association.new(Picture, association, :has_many, proc { where(name: self.name) }, {})
|
136
161
|
end
|
137
162
|
end
|
138
163
|
|
139
164
|
def errors
|
140
165
|
@errors ||= begin
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
166
|
+
errors = ActiveModel::Errors.new(self)
|
167
|
+
errors.add(:name, "can't be blank")
|
168
|
+
errors.add(:description, 'must be longer than 15 characters')
|
169
|
+
errors.add(:age, 'is not a number')
|
170
|
+
errors.add(:age, 'must be greater than 18')
|
171
|
+
errors.add(:company, 'company must be present')
|
172
|
+
errors.add(:company_id, 'must be valid')
|
173
|
+
errors
|
149
174
|
end
|
150
175
|
end
|
151
176
|
|