simple_form 1.4.2 → 1.5.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.
Potentially problematic release.
This version of simple_form might be problematic. Click here for more details.
- data/.gitignore +1 -0
- data/.travis.yml +9 -1
- data/CHANGELOG.rdoc +20 -0
- data/Gemfile +5 -4
- data/README.rdoc +2 -2
- data/Rakefile +1 -1
- data/lib/generators/simple_form/install_generator.rb +2 -6
- data/lib/generators/simple_form/templates/{simple_form.rb → config/initializers/simple_form.rb} +0 -0
- data/lib/generators/simple_form/templates/{en.yml → config/locales/simple_form.en.yml} +0 -0
- data/lib/simple_form.rb +1 -1
- data/lib/simple_form/action_view_extensions/builder.rb +12 -5
- data/lib/simple_form/action_view_extensions/form_helper.rb +13 -8
- data/lib/simple_form/components.rb +1 -1
- data/lib/simple_form/components/errors.rb +10 -2
- data/lib/simple_form/components/hints.rb +10 -0
- data/lib/simple_form/components/label_input.rb +5 -3
- data/lib/simple_form/components/labels.rb +10 -4
- data/lib/simple_form/components/placeholders.rb +10 -4
- data/lib/simple_form/error_notification.rb +1 -1
- data/lib/simple_form/form_builder.rb +10 -7
- data/lib/simple_form/helpers.rb +9 -0
- data/lib/simple_form/helpers/has_errors.rb +15 -0
- data/lib/simple_form/helpers/maxlength.rb +24 -0
- data/lib/simple_form/helpers/pattern.rb +28 -0
- data/lib/simple_form/helpers/required.rb +36 -0
- data/lib/simple_form/helpers/validators.rb +44 -0
- data/lib/simple_form/inputs.rb +5 -2
- data/lib/simple_form/inputs/base.rb +24 -47
- data/lib/simple_form/inputs/boolean_input.rb +1 -1
- data/lib/simple_form/inputs/collection_input.rb +1 -1
- data/lib/simple_form/inputs/date_time_input.rb +1 -1
- data/lib/simple_form/inputs/file_input.rb +9 -0
- data/lib/simple_form/inputs/hidden_input.rb +1 -1
- data/lib/simple_form/inputs/numeric_input.rb +20 -13
- data/lib/simple_form/inputs/password_input.rb +13 -0
- data/lib/simple_form/inputs/range_input.rb +16 -0
- data/lib/simple_form/inputs/string_input.rb +7 -24
- data/lib/simple_form/inputs/text_input.rb +12 -0
- data/lib/simple_form/version.rb +1 -1
- data/test/action_view_extensions/builder_test.rb +59 -0
- data/test/action_view_extensions/form_helper_test.rb +21 -0
- data/test/discovery_inputs.rb +2 -2
- data/test/form_builder_test.rb +54 -0
- data/test/inputs_test.rb +185 -20
- data/test/support/models.rb +23 -2
- data/test/test_helper.rb +1 -0
- metadata +17 -11
- data/Gemfile.lock +0 -54
- data/init.rb +0 -1
- data/lib/simple_form/has_errors.rb +0 -14
- data/lib/simple_form/inputs/mapping_input.rb +0 -29
@@ -47,6 +47,16 @@ class FormHelperTest < ActionView::TestCase
|
|
47
47
|
assert_select 'form.simple_form.user'
|
48
48
|
end
|
49
49
|
|
50
|
+
test 'simple form should not add object class to form if css_class is specified' do
|
51
|
+
concat(simple_form_for(:user, :html => {:class => nil}) do |f| end)
|
52
|
+
assert_no_select 'form.user'
|
53
|
+
end
|
54
|
+
|
55
|
+
test 'simple form should add custom class to form if css_class is specified' do
|
56
|
+
concat(simple_form_for(:user, :html => {:class => 'my_class'}) do |f| end)
|
57
|
+
assert_select 'form.my_class'
|
58
|
+
end
|
59
|
+
|
50
60
|
test 'pass options to simple form' do
|
51
61
|
concat(simple_form_for(:user, :url => '/account', :html => { :id => 'my_form' }) do |f| end)
|
52
62
|
assert_select 'form#my_form'
|
@@ -58,4 +68,15 @@ class FormHelperTest < ActionView::TestCase
|
|
58
68
|
assert f.instance_of?(SimpleForm::FormBuilder)
|
59
69
|
end)
|
60
70
|
end
|
71
|
+
|
72
|
+
test 'fields for with a hash like model yeilds an instance of FormBuilder' do
|
73
|
+
@hash_backed_author = HashBackedAuthor.new
|
74
|
+
|
75
|
+
concat(simple_fields_for(:author, @hash_backed_author) do |f|
|
76
|
+
assert f.instance_of?(SimpleForm::FormBuilder)
|
77
|
+
f.input :name
|
78
|
+
end)
|
79
|
+
|
80
|
+
assert_select "input[name='author[name]'][value='hash backed author']"
|
81
|
+
end
|
61
82
|
end
|
data/test/discovery_inputs.rb
CHANGED
data/test/form_builder_test.rb
CHANGED
@@ -338,6 +338,8 @@ class FormBuilderTest < ActionView::TestCase
|
|
338
338
|
assert_select 'input.optional#user_name'
|
339
339
|
end
|
340
340
|
|
341
|
+
# VALIDATORS :if :unless
|
342
|
+
|
341
343
|
test 'builder input should not be required when ActiveModel::Validations is included and if option is present' do
|
342
344
|
with_form_for @validating_user, :age
|
343
345
|
assert_no_select 'input.required'
|
@@ -352,7 +354,53 @@ class FormBuilderTest < ActionView::TestCase
|
|
352
354
|
assert_select 'input.optional#validating_user_amount'
|
353
355
|
end
|
354
356
|
|
357
|
+
# VALIDATORS :on
|
358
|
+
|
359
|
+
test 'builder input should be required when validation is on create and is not persisted' do
|
360
|
+
@validating_user.new_record!
|
361
|
+
with_form_for @validating_user, :action
|
362
|
+
assert_select 'input.required'
|
363
|
+
assert_select 'input[required]'
|
364
|
+
assert_select 'input.required[required]#validating_user_action'
|
365
|
+
end
|
366
|
+
|
367
|
+
test 'builder input should not be required when validation is on create and is persisted' do
|
368
|
+
with_form_for @validating_user, :action
|
369
|
+
assert_no_select 'input.required'
|
370
|
+
assert_no_select 'input[required]'
|
371
|
+
assert_select 'input.optional#validating_user_action'
|
372
|
+
end
|
373
|
+
|
374
|
+
test 'builder input should be required when validation is on save' do
|
375
|
+
with_form_for @validating_user, :credit_limit
|
376
|
+
assert_select 'input.required'
|
377
|
+
assert_select 'input[required]'
|
378
|
+
assert_select 'input.required[required]#validating_user_credit_limit'
|
379
|
+
|
380
|
+
@validating_user.new_record!
|
381
|
+
with_form_for @validating_user, :credit_limit
|
382
|
+
assert_select 'input.required'
|
383
|
+
assert_select 'input[required]'
|
384
|
+
assert_select 'input.required[required]#validating_user_credit_limit'
|
385
|
+
end
|
386
|
+
|
387
|
+
test 'builder input should be required when validation is on update and is persisted' do
|
388
|
+
with_form_for @validating_user, :phone_number
|
389
|
+
assert_select 'input.required'
|
390
|
+
assert_select 'input[required]'
|
391
|
+
assert_select 'input.required[required]#validating_user_phone_number'
|
392
|
+
end
|
393
|
+
|
394
|
+
test 'builder input should not be required when validation is on update and is not persisted' do
|
395
|
+
@validating_user.new_record!
|
396
|
+
with_form_for @validating_user, :phone_number
|
397
|
+
assert_no_select 'input.required'
|
398
|
+
assert_no_select 'input[required]'
|
399
|
+
assert_select 'input.optional#validating_user_phone_number'
|
400
|
+
end
|
401
|
+
|
355
402
|
# WRAPPERS
|
403
|
+
|
356
404
|
test 'builder support wrapping around an specific tag' do
|
357
405
|
swap SimpleForm, :wrapper_tag => :p do
|
358
406
|
with_form_for @user, :name
|
@@ -361,6 +409,12 @@ class FormBuilderTest < ActionView::TestCase
|
|
361
409
|
end
|
362
410
|
end
|
363
411
|
|
412
|
+
test 'builder support no wrapping when wrapper is false' do
|
413
|
+
with_form_for @user, :name, :wrapper => false
|
414
|
+
assert_select 'form > label[for=user_name]'
|
415
|
+
assert_select 'form > input#user_name.string'
|
416
|
+
end
|
417
|
+
|
364
418
|
test 'builder wrapping tag adds default css classes' do
|
365
419
|
swap SimpleForm, :wrapper_tag => :p do
|
366
420
|
with_form_for @user, :name
|
data/test/inputs_test.rb
CHANGED
@@ -141,9 +141,9 @@ class InputTest < ActionView::TestCase
|
|
141
141
|
assert_select "input#user_password.password[type=password][name='user[password]']"
|
142
142
|
end
|
143
143
|
|
144
|
-
test 'input should use
|
144
|
+
test 'input should not use size attribute for decimal attributes' do
|
145
145
|
with_input_for @user, :credit_limit, :decimal
|
146
|
-
|
146
|
+
assert_no_select 'input.decimal[size]'
|
147
147
|
end
|
148
148
|
|
149
149
|
test 'input should get maxlength from column definition for string attributes' do
|
@@ -151,6 +151,11 @@ class InputTest < ActionView::TestCase
|
|
151
151
|
assert_select 'input.string[maxlength=100]'
|
152
152
|
end
|
153
153
|
|
154
|
+
test 'input should not get maxlength from column without size definition for string attributes' do
|
155
|
+
with_input_for @user, :action, :string
|
156
|
+
assert_no_select 'input.string[maxlength]'
|
157
|
+
end
|
158
|
+
|
154
159
|
test 'input should get size from column definition for string attributes respecting maximum value' do
|
155
160
|
with_input_for @user, :name, :string
|
156
161
|
assert_select 'input.string[size=50]'
|
@@ -166,6 +171,11 @@ class InputTest < ActionView::TestCase
|
|
166
171
|
assert_select 'input.password[type=password][maxlength=100]'
|
167
172
|
end
|
168
173
|
|
174
|
+
test 'input should infer maxlength column definition from validation when present' do
|
175
|
+
with_input_for @validating_user, :name, :string
|
176
|
+
assert_select 'input.string[maxlength=25]'
|
177
|
+
end
|
178
|
+
|
169
179
|
test 'when not using HTML5, does not show maxlength attribute' do
|
170
180
|
swap SimpleForm, :html5 => false do
|
171
181
|
with_input_for @user, :password, :password
|
@@ -173,6 +183,13 @@ class InputTest < ActionView::TestCase
|
|
173
183
|
end
|
174
184
|
end
|
175
185
|
|
186
|
+
test 'when not using HTML5, does not show maxlength attribute with validating lenght attribute' do
|
187
|
+
swap SimpleForm, :html5 => false do
|
188
|
+
with_input_for @validating_user, :name, :string
|
189
|
+
assert_no_select 'input.string[maxlength]'
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
176
193
|
test 'input should not generate placeholder by default' do
|
177
194
|
with_input_for @user, :name, :string
|
178
195
|
assert_no_select 'input[placeholder]'
|
@@ -212,6 +229,22 @@ class InputTest < ActionView::TestCase
|
|
212
229
|
end
|
213
230
|
end
|
214
231
|
|
232
|
+
test 'input should infer pattern from attributes when pattern is true' do
|
233
|
+
with_input_for @other_validating_user, :country, :string, :pattern => true
|
234
|
+
assert_select 'input[pattern="\w+"]'
|
235
|
+
end
|
236
|
+
|
237
|
+
test 'input should use given pattern from attributes' do
|
238
|
+
with_input_for @other_validating_user, :country, :string, :pattern => "\\d+"
|
239
|
+
assert_select 'input[pattern="\d+"]'
|
240
|
+
end
|
241
|
+
|
242
|
+
test 'input should fail if pattern is true but no pattern exists' do
|
243
|
+
assert_raise RuntimeError do
|
244
|
+
with_input_for @other_validating_user, :name, :string, :pattern => true
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
215
248
|
# NumericInput
|
216
249
|
test 'input should generate an integer text field for integer attributes ' do
|
217
250
|
with_input_for @user, :age, :integer
|
@@ -345,16 +378,28 @@ class InputTest < ActionView::TestCase
|
|
345
378
|
end
|
346
379
|
end
|
347
380
|
|
381
|
+
[:integer, :float, :decimal].each do |type|
|
382
|
+
test "#{type} input should infer min value from attributes with greater than or equal validation" do
|
383
|
+
with_input_for @validating_user, :age, type
|
384
|
+
assert_select 'input[min=18]'
|
385
|
+
end
|
386
|
+
|
387
|
+
test "#{type} input should infer the max value from attributes with less than or equal to validation" do
|
388
|
+
with_input_for @validating_user, :age, type
|
389
|
+
assert_select 'input[max=99]'
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
348
393
|
# Numeric input but HTML5 disabled
|
349
|
-
test '
|
394
|
+
test 'when not using HTML5 input should not generate field with type number and use text instead' do
|
350
395
|
swap SimpleForm, :html5 => false do
|
351
396
|
with_input_for @user, :age, :integer
|
352
397
|
assert_no_select "input[type=number]"
|
353
|
-
|
398
|
+
assert_select "input#user_age[type=text]"
|
354
399
|
end
|
355
400
|
end
|
356
401
|
|
357
|
-
test 'when not using HTML5 input should not use min or max or step attributes' do
|
402
|
+
test 'when not using HTML5 input should not use min or max or step attributes for numeric type' do
|
358
403
|
swap SimpleForm, :html5 => false do
|
359
404
|
with_input_for @validating_user, :age, :integer
|
360
405
|
assert_no_select "input[min]"
|
@@ -363,15 +408,63 @@ class InputTest < ActionView::TestCase
|
|
363
408
|
end
|
364
409
|
end
|
365
410
|
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
411
|
+
# RangeInput
|
412
|
+
test 'range input generates a input type range, based on numeric input' do
|
413
|
+
with_input_for @user, :age, :range
|
414
|
+
assert_select "input#user_age.range[type=range]"
|
415
|
+
end
|
416
|
+
|
417
|
+
test 'range input does not generate placeholder' do
|
418
|
+
with_input_for @user, :age, :range, :placeholder => "Select your age"
|
419
|
+
assert_select "input[type=range]"
|
420
|
+
assert_no_select "input[placeholder]"
|
421
|
+
end
|
422
|
+
|
423
|
+
test 'range input allows givin min and max attributes' do
|
424
|
+
with_input_for @user, :age, :range, :input_html => { :min => 10, :max => 50 }
|
425
|
+
assert_select "input[type=range][min=10][max=50]"
|
426
|
+
end
|
427
|
+
|
428
|
+
test 'range input infers min and max attributes from validations' do
|
429
|
+
with_input_for @validating_user, :age, :range
|
430
|
+
assert_select "input[type=range][min=18][max=99]"
|
431
|
+
end
|
432
|
+
|
433
|
+
test 'range input add default step attribute' do
|
434
|
+
with_input_for @validating_user, :age, :range
|
435
|
+
assert_select "input[type=range][step=1]"
|
436
|
+
end
|
437
|
+
|
438
|
+
test 'range input allows givin a step through input html options' do
|
439
|
+
with_input_for @validating_user, :age, :range, :input_html => { :step => 2 }
|
440
|
+
assert_select "input[type=range][step=2]"
|
441
|
+
end
|
442
|
+
|
443
|
+
test 'range input should not generate min attribute by default' do
|
444
|
+
with_input_for @user, :age, :range
|
445
|
+
assert_no_select 'input[min]'
|
446
|
+
end
|
447
|
+
|
448
|
+
test 'range input should not generate max attribute by default' do
|
449
|
+
with_input_for @user, :age, :range
|
450
|
+
assert_no_select 'input[max]'
|
451
|
+
end
|
452
|
+
|
453
|
+
# RangeInput iwth HTML5 disabled
|
454
|
+
test 'when not using HTML5, range input does not generate field with range type, and use text instead' do
|
455
|
+
swap SimpleForm, :html5 => false do
|
456
|
+
with_input_for @user, :age, :range
|
457
|
+
assert_no_select "input[type=number]"
|
458
|
+
assert_select "input[type=text]"
|
370
459
|
end
|
460
|
+
end
|
371
461
|
|
372
|
-
|
373
|
-
|
374
|
-
|
462
|
+
test 'when not using HTML5, range input should not use min or max or step attributes' do
|
463
|
+
swap SimpleForm, :html5 => false do
|
464
|
+
with_input_for @validating_user, :age, :range
|
465
|
+
assert_no_select "input[min]"
|
466
|
+
assert_no_select "input[max]"
|
467
|
+
assert_no_select "input[step]"
|
375
468
|
end
|
376
469
|
end
|
377
470
|
|
@@ -393,6 +486,30 @@ class InputTest < ActionView::TestCase
|
|
393
486
|
assert_select 'textarea.text[placeholder=Put in some text]'
|
394
487
|
end
|
395
488
|
|
489
|
+
test 'input should get maxlength from column definition for text attributes' do
|
490
|
+
with_input_for @user, :description, :text
|
491
|
+
assert_select 'textarea.text[maxlength=200]'
|
492
|
+
end
|
493
|
+
|
494
|
+
test 'input should infer maxlength column definition from validation when present for text attributes' do
|
495
|
+
with_input_for @validating_user, :description, :text
|
496
|
+
assert_select 'textarea.text[maxlength=50]'
|
497
|
+
end
|
498
|
+
|
499
|
+
test 'when not using HTML5, does not show maxlength attribute for text attributes' do
|
500
|
+
swap SimpleForm, :html5 => false do
|
501
|
+
with_input_for @user, :description, :text
|
502
|
+
assert_no_select 'textarea.text[maxlength]'
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
test 'when not using HTML5, does not show maxlength attribute with validating lenght text attribute' do
|
507
|
+
swap SimpleForm, :html5 => false do
|
508
|
+
with_input_for @validating_user, :name, :string
|
509
|
+
assert_no_select 'input.string[maxlength]'
|
510
|
+
end
|
511
|
+
end
|
512
|
+
|
396
513
|
test 'input should generate a file field' do
|
397
514
|
with_input_for @user, :name, :file
|
398
515
|
assert_select 'input#user_name[type=file]'
|
@@ -403,14 +520,6 @@ class InputTest < ActionView::TestCase
|
|
403
520
|
assert_no_select 'input[placeholder]'
|
404
521
|
end
|
405
522
|
|
406
|
-
test 'mapping input should generate an error if type is not found' do
|
407
|
-
with_concat_form_for(@user) do |f|
|
408
|
-
assert_raise(RuntimeError, "Could not find method for nil") do
|
409
|
-
SimpleForm::Inputs::MappingInput.new(f, "unknown", nil, nil, {}).input
|
410
|
-
end
|
411
|
-
end
|
412
|
-
end
|
413
|
-
|
414
523
|
# HiddenInput
|
415
524
|
test 'input should generate a hidden field' do
|
416
525
|
with_input_for @user, :name, :hidden
|
@@ -674,6 +783,62 @@ class InputTest < ActionView::TestCase
|
|
674
783
|
assert_select 'select option[value=2]', 'Carlos'
|
675
784
|
end
|
676
785
|
|
786
|
+
test 'input should disable the anothers components when the option is a object' do
|
787
|
+
with_input_for @user, :description, :select, :collection => ["Jose", "Carlos"], :disabled => true
|
788
|
+
assert_no_select 'select option[value=Jose][disabled=disabled]', 'Jose'
|
789
|
+
assert_no_select 'select option[value=Carlos][disabled=disabled]', 'Carlos'
|
790
|
+
assert_select 'select[disabled=disabled]'
|
791
|
+
assert_select 'div.disabled'
|
792
|
+
end
|
793
|
+
|
794
|
+
test 'input should not disable the anothers components when the option is a object' do
|
795
|
+
with_input_for @user, :description, :select, :collection => ["Jose", "Carlos"], :disabled => 'Jose'
|
796
|
+
assert_select 'select option[value=Jose][disabled=disabled]', 'Jose'
|
797
|
+
assert_no_select 'select option[value=Carlos][disabled=disabled]', 'Carlos'
|
798
|
+
assert_no_select 'select[disabled=disabled]'
|
799
|
+
assert_no_select 'div.disabled'
|
800
|
+
end
|
801
|
+
|
802
|
+
test 'input should allow disabled options with a lambda for collection select' do
|
803
|
+
with_input_for @user, :name, :select, :collection => ["Carlos", "Antonio"],
|
804
|
+
:disabled => lambda { |x| x == "Carlos" }
|
805
|
+
assert_select 'select option[value=Carlos][disabled=disabled]', 'Carlos'
|
806
|
+
assert_select 'select option[value=Antonio]', 'Antonio'
|
807
|
+
assert_no_select 'select option[value=Antonio][disabled]'
|
808
|
+
end
|
809
|
+
|
810
|
+
test 'input should allow disabled and label method with lambdas for collection select' do
|
811
|
+
with_input_for @user, :name, :select, :collection => ["Carlos", "Antonio"],
|
812
|
+
:disabled => lambda { |x| x == "Carlos" }, :label_method => lambda { |x| x.upcase }
|
813
|
+
assert_select 'select option[value=Carlos][disabled=disabled]', 'CARLOS'
|
814
|
+
assert_select 'select option[value=Antonio]', 'ANTONIO'
|
815
|
+
assert_no_select 'select option[value=Antonio][disabled]'
|
816
|
+
end
|
817
|
+
|
818
|
+
test 'input should allow a non lambda disabled option with lambda label method for collections' do
|
819
|
+
with_input_for @user, :name, :select, :collection => ["Carlos", "Antonio"],
|
820
|
+
:disabled => "Carlos", :label_method => lambda { |x| x.upcase }
|
821
|
+
assert_select 'select option[value=Carlos][disabled=disabled]', 'CARLOS'
|
822
|
+
assert_select 'select option[value=Antonio]', 'ANTONIO'
|
823
|
+
assert_no_select 'select option[value=Antonio][disabled]'
|
824
|
+
end
|
825
|
+
|
826
|
+
test 'input should allow selected and label method with lambdas for collection select' do
|
827
|
+
with_input_for @user, :name, :select, :collection => ["Carlos", "Antonio"],
|
828
|
+
:selected => lambda { |x| x == "Carlos" }, :label_method => lambda { |x| x.upcase }
|
829
|
+
assert_select 'select option[value=Carlos][selected=selected]', 'CARLOS'
|
830
|
+
assert_select 'select option[value=Antonio]', 'ANTONIO'
|
831
|
+
assert_no_select 'select option[value=Antonio][selected]'
|
832
|
+
end
|
833
|
+
|
834
|
+
test 'input should allow a non lambda selected option with lambda label method for collection select' do
|
835
|
+
with_input_for @user, :name, :select, :collection => ["Carlos", "Antonio"],
|
836
|
+
:selected => "Carlos", :label_method => lambda { |x| x.upcase }
|
837
|
+
assert_select 'select option[value=Carlos][selected=selected]', 'CARLOS'
|
838
|
+
assert_select 'select option[value=Antonio]', 'ANTONIO'
|
839
|
+
assert_no_select 'select option[value=Antonio][selected]'
|
840
|
+
end
|
841
|
+
|
677
842
|
test 'input should allow overriding collection for radio types' do
|
678
843
|
with_input_for @user, :name, :radio, :collection => ['Jose', 'Carlos']
|
679
844
|
assert_select 'input[type=radio][value=Jose]'
|
data/test/support/models.rb
CHANGED
@@ -42,7 +42,7 @@ class User
|
|
42
42
|
:description, :created_at, :updated_at, :credit_limit, :password, :url,
|
43
43
|
:delivery_time, :born_at, :special_company_id, :country, :tags, :tag_ids,
|
44
44
|
:avatar, :home_picture, :email, :status, :residence_country, :phone_number,
|
45
|
-
:post_count, :lock_version, :amount, :attempts
|
45
|
+
:post_count, :lock_version, :amount, :attempts, :action
|
46
46
|
|
47
47
|
def initialize(options={})
|
48
48
|
options.each do |key, value|
|
@@ -67,7 +67,7 @@ class User
|
|
67
67
|
def column_for_attribute(attribute)
|
68
68
|
column_type, limit = case attribute.to_sym
|
69
69
|
when :name, :status, :password then [:string, 100]
|
70
|
-
when :description then :text
|
70
|
+
when :description then [:text, 200]
|
71
71
|
when :age then :integer
|
72
72
|
when :credit_limit then [:decimal, 15]
|
73
73
|
when :active then :boolean
|
@@ -79,6 +79,7 @@ class User
|
|
79
79
|
when :home_picture then :string
|
80
80
|
when :amount then :integer
|
81
81
|
when :attempts then :integer
|
82
|
+
when :action then :string
|
82
83
|
end
|
83
84
|
Column.new(attribute, column_type, limit)
|
84
85
|
end
|
@@ -129,6 +130,11 @@ class ValidatingUser < User
|
|
129
130
|
validates :company, :presence => true
|
130
131
|
validates :age, :presence => true, :if => Proc.new { |user| user.name }
|
131
132
|
validates :amount, :presence => true, :unless => Proc.new { |user| user.age }
|
133
|
+
|
134
|
+
validates :action, :presence => true, :on => :create
|
135
|
+
validates :credit_limit, :presence => true, :on => :save
|
136
|
+
validates :phone_number, :presence => true, :on => :update
|
137
|
+
|
132
138
|
validates_numericality_of :age,
|
133
139
|
:greater_than_or_equal_to => 18,
|
134
140
|
:less_than_or_equal_to => 99,
|
@@ -141,6 +147,8 @@ class ValidatingUser < User
|
|
141
147
|
:greater_than_or_equal_to => :min_attempts,
|
142
148
|
:less_than_or_equal_to => :max_attempts,
|
143
149
|
:only_integer => true
|
150
|
+
validates_length_of :name, :maximum => 25
|
151
|
+
validates_length_of :description, :maximum => 50
|
144
152
|
|
145
153
|
def min_amount
|
146
154
|
10
|
@@ -173,4 +181,17 @@ class OtherValidatingUser < User
|
|
173
181
|
:greater_than_or_equal_to => Proc.new { |user| user.age },
|
174
182
|
:less_than_or_equal_to => Proc.new { |user| user.age + 100},
|
175
183
|
:only_integer => true
|
184
|
+
|
185
|
+
validates_format_of :country, :with => /\w+/
|
186
|
+
end
|
187
|
+
|
188
|
+
class HashBackedAuthor < Hash
|
189
|
+
extend ActiveModel::Naming
|
190
|
+
include ActiveModel::Conversion
|
191
|
+
|
192
|
+
def persisted?; false; end
|
193
|
+
|
194
|
+
def name
|
195
|
+
'hash backed author'
|
196
|
+
end
|
176
197
|
end
|