formtastic 3.1.0.rc1 → 3.1.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,4 +1,8 @@
1
- 3.1.0.rc1 (unreleased)
1
+ 3.1.0.rc2
2
+
3
+ * Deprecated :member_value and :member_label options
4
+
5
+ 3.1.0.rc1
2
6
 
3
7
  * Deprecated support for Rails version < 4.1.0
4
8
  * Fixed synchronization issues with custom_namespace configuration
data/DEPRECATIONS CHANGED
@@ -9,6 +9,8 @@ v4.0 (planned)
9
9
  v3.1 (master)
10
10
 
11
11
  * Deprecate support for Rails < 4.1
12
+ * Deprecate :member_value option
13
+ * Deprecate :member_label option
12
14
 
13
15
  v3.0
14
16
 
data/README.textile CHANGED
@@ -191,7 +191,7 @@ If you want to customize the label text, or render some hint text below the fiel
191
191
  <%= f.inputs :name => "Advanced Options", :id => "advanced" do %>
192
192
  <%= f.input :slug, :label => "URL Title", :hint => "Created automatically if left blank", :required => false %>
193
193
  <%= f.input :section, :as => :radio %>
194
- <%= f.input :user, :label => "Author", :member_label => :full_name %>
194
+ <%= f.input :user, :label => "Author" %>
195
195
  <%= f.input :categories, :required => false %>
196
196
  <%= f.input :created_at, :as => :string, :label => "Publication Date", :required => false %>
197
197
  <% end %>
@@ -308,6 +308,9 @@ Many inputs provide a collection of options to choose from (like @:select@, @:ra
308
308
  f.input :authors, :as => :check_boxes, :collection => [@justin, @kate]
309
309
  f.input :authors, :as => :check_boxes, :collection => ["Justin", "Kate", "Amelia", "Gus", "Meg"]
310
310
  f.input :author, :as => :select, :collection => Author.all
311
+ f.input :author, :as => :select, :collection => Author.pluck(:first_name, :id)
312
+ f.input :author, :as => :select, :collection => Author.pluck(Arel.sql("CONCAT(`first_name`, ' ', `last_name`)"), :id)
313
+ f.input :author, :as => :select, :collection => Author.your_custom_scope_or_class_method
311
314
  f.input :author, :as => :select, :collection => { @justin.name => @justin.id, @kate.name => @kate.id }
312
315
  f.input :author, :as => :select, :collection => ["Justin", "Kate", "Amelia", "Gus", "Meg"]
313
316
  f.input :author, :as => :radio, :collection => User.all
@@ -141,12 +141,6 @@ module Formtastic
141
141
  # @option options :collection [Array<ActiveModel, String, Symbol>, Hash{String => String, Boolean}, OrderedHash{String => String, Boolean}]
142
142
  # Override collection of objects in the association (`:select`, `:radio` & `:check_boxes` inputs only)
143
143
  #
144
- # @option options :member_label [Symbol, Proc, Method]
145
- # Override the method called on each object in the `:collection` for use as the `<label>` content (`:check_boxes` & `:radio` inputs) or `<option>` content (`:select` inputs)
146
- #
147
- # @option options :member_value [Symbol, Proc, Method]
148
- # Override the method called on each object in the `:collection` for use as the `value` attribute in the `<input>` (`:check_boxes` & `:radio` inputs) or `<option>` (`:select` inputs)
149
- #
150
144
  # @option options :multiple [Boolean]
151
145
  # Specify if the `:select` input should allow multiple selections or not (defaults to `belongs_to` associations, and `true` for `has_many` and `has_and_belongs_to_many` associations)
152
146
  #
@@ -11,6 +11,11 @@ module Formtastic
11
11
  @object_name = object_name
12
12
  @method = method
13
13
  @options = options.dup
14
+
15
+ # Deprecate :member_label and :member_value, remove v4.0
16
+ member_deprecation_message = "passing an Array of label/value pairs like [['Justin', 2], ['Kate', 3]] into :collection directly (consider building the array in your model using Model.pluck)"
17
+ warn_deprecated_option!(:member_label, member_deprecation_message)
18
+ warn_deprecated_option!(:member_value, member_deprecation_message)
14
19
  end
15
20
 
16
21
  # Usefull for deprecating options.
@@ -24,7 +29,7 @@ module Formtastic
24
29
  # Usefull for deprecating options.
25
30
  def warn_deprecated_option!(old_option_name, instructions)
26
31
  if options.key?(old_option_name)
27
- ::ActiveSupport::Deprecation.warn("The :#{old_option_name} option is deprecated in favour of `#{instructions}` and will be removed in the next version", caller(6))
32
+ ::ActiveSupport::Deprecation.warn("The :#{old_option_name} option is deprecated in favour of `#{instructions}`. :#{old_option_name} will be removed in the next version", caller(6))
28
33
  end
29
34
  end
30
35
 
@@ -39,6 +39,7 @@ module Formtastic
39
39
  # <%= f.input :categories, :as => :check_boxes, :collection => @categories %>
40
40
  # <%= f.input :categories, :as => :check_boxes, :collection => Category.all %>
41
41
  # <%= f.input :categories, :as => :check_boxes, :collection => Category.some_named_scope %>
42
+ # <%= f.input :categories, :as => :check_boxes, :collection => Category.pluck(:label, :id) %>
42
43
  # <%= f.input :categories, :as => :check_boxes, :collection => [Category.find_by_name("Ruby"), Category.find_by_name("Rails")] %>
43
44
  # <%= f.input :categories, :as => :check_boxes, :collection => ["Ruby", "Rails"] %>
44
45
  # <%= f.input :categories, :as => :check_boxes, :collection => [["Ruby", "ruby"], ["Rails", "rails"]] %>
@@ -56,24 +57,6 @@ module Formtastic
56
57
  # @example `:disabled` can be used to disable any checkboxes with a value found in the given Array
57
58
  # <%= f.input :categories, :as => :check_boxes, :collection => ["a", "b"], :disabled => ["a"] %>
58
59
  #
59
- # @example `:member_label` can be used to call a different method (or a Proc) on each object in the collection for rendering the label text (it'll try the methods like `to_s` in `collection_label_methods` config by default)
60
- # <%= f.input :categories, :as => :check_boxes, :member_label => :name %>
61
- # <%= f.input :categories, :as => :check_boxes, :member_label => :name_with_post_count
62
- # <%= f.input :categories, :as => :check_boxes, :member_label => { |c| "#{c.name} (#{pluralize("post", c.posts.count)})" }
63
- #
64
- # @example `:member_label` can be used with a helper method (both examples have the same result)
65
- # <%= f.input :categories, :as => :check_boxes, :member_label => method(:fancy_label)
66
- # <%= f.input :categories, :as => :check_boxes, :member_label => Proc.new { |category| fancy_label(category) }
67
- #
68
- # @example `:member_value` can be used to call a different method (or a Proc) on each object in the collection for rendering the value for each checkbox (it'll try the methods like `id` in `collection_value_methods` config by default)
69
- # <%= f.input :categories, :as => :check_boxes, :member_value => :code %>
70
- # <%= f.input :categories, :as => :check_boxes, :member_value => :isbn
71
- # <%= f.input :categories, :as => :check_boxes, :member_value => Proc.new { |c| c.name.downcase.underscore }
72
- #
73
- # @example `:member_value` can be used with a helper method (both examples have the same result)
74
- # <%= f.input :categories, :as => :check_boxes, :member_value => method(:some_helper)
75
- # <%= f.input :categories, :as => :check_boxes, :member_value => Proc.new { |category| some_helper(category) }
76
- #
77
60
  # @example `:value_as_class` can be used to add a class to the `<li>` wrapped around each choice using the checkbox value for custom styling of each choice
78
61
  # <%= f.input :categories, :as => :check_boxes, :value_as_class => true %>
79
62
  #
@@ -31,10 +31,9 @@ module Formtastic
31
31
  # `Section.all` for a `Post` form with an input for a `belongs_to :section` association.
32
32
  # You can override or customise this collection through the `:collection` option (see examples).
33
33
  #
34
- # The way on which Formtastic renders the `value` attribute and label for each choice is
35
- # customisable through the `:member_label` and `:member_value` options (see examples below).
36
- # When not provided, we fall back to a list of methods to try on each object such as
37
- # `:to_label`, `:name` and `:to_s`, which are defined in the configurations
34
+ # The way on which Formtastic renders the `value` attribute and label for each choice in the `:collection` is
35
+ # customisable (see examples below). When not provided, we fall back to a list of methods to try on each
36
+ # object such as `:to_label`, `:name` and `:to_s`, which are defined in the configurations
38
37
  # `collection_label_methods` and `collection_value_methods`.
39
38
  #
40
39
  # @example Basic `belongs_to` example with full form context
@@ -78,6 +77,8 @@ module Formtastic
78
77
  # <%= f.input :author, :as => :radio, :collection => @authors %>
79
78
  # <%= f.input :author, :as => :radio, :collection => Author.all %>
80
79
  # <%= f.input :author, :as => :radio, :collection => Author.some_named_scope %>
80
+ # <%= f.input :author, :as => :radio, :collection => Author.pluck(:full_name, :id) %>
81
+ # <%= f.input :author, :as => :radio, :collection => Author.pluck(Arel.sql("CONCAT(`first_name`, ' ', `last_name`)"), :id)) %>
81
82
  # <%= f.input :author, :as => :radio, :collection => [Author.find_by_login("justin"), Category.find_by_name("kate")] %>
82
83
  # <%= f.input :author, :as => :radio, :collection => ["Justin", "Kate"] %>
83
84
  # <%= f.input :author, :as => :radio, :collection => [["Justin", "justin"], ["Kate", "kate"]] %>
@@ -87,23 +88,6 @@ module Formtastic
87
88
  # <%= f.input :author, :as => :radio, :collection => [:justin, :kate] %>
88
89
  # <%= f.input :author, :as => :radio, :collection => 1..5 %>
89
90
  #
90
- # @example The `:member_label` can be used to call a different method (or a Proc) on each object in the collection for rendering the label text (it'll try the methods like `to_s` in `collection_label_methods` config by default)
91
- # <%= f.input :author, :as => :radio, :member_label => :name %>
92
- # <%= f.input :author, :as => :radio, :member_label => :name_with_post_count
93
- # <%= f.input :author, :as => :radio, :member_label => Proc.new { |a| "#{c.name} (#{pluralize("post", a.posts.count)})" }
94
- #
95
- # @example `:member_label` can be used with a helper method (both examples have the same result)
96
- # <%= f.input :author, :as => :radio, :member_label => method(:fancy_label)
97
- # <%= f.input :author, :as => :radio, :member_label => Proc.new { |author| fancy_label(author) }
98
- #
99
- # @example The `:member_value` can be used to call a different method (or a Proc) on each object in the collection for rendering the value for each checkbox (it'll try the methods like `id` in `collection_value_methods` config by default)
100
- # <%= f.input :author, :as => :radio, :member_value => :login %>
101
- # <%= f.input :author, :as => :radio, :member_value => Proc.new { |c| c.full_name.downcase.underscore }
102
- #
103
- # @example `:member_value` can be used with a helper method (both examples have the same result)
104
- # <%= f.input :author, :as => :radio, :member_value => method(:some_helper)
105
- # <%= f.input :author, :as => :radio, :member_value => Proc.new { |author| some_helper(author) }
106
- #
107
91
  # @example Set HTML attributes on each `<input type="radio">` tag with `:input_html`
108
92
  # <%= f.input :author, :as => :radio, :input_html => { :size => 20, :multiple => true, :class => "special" } %>
109
93
  #
@@ -94,6 +94,8 @@ module Formtastic
94
94
  # <%= f.input :author, :as => :select, :collection => @authors %>
95
95
  # <%= f.input :author, :as => :select, :collection => Author.all %>
96
96
  # <%= f.input :author, :as => :select, :collection => Author.some_named_scope %>
97
+ # <%= f.input :author, :as => :select, :collection => Author.pluck(:full_name, :id) %>
98
+ # <%= f.input :author, :as => :select, :collection => Author.pluck(Arel.sql("CONCAT(`first_name`, ' ', `last_name`)"), :id)) %>
97
99
  # <%= f.input :author, :as => :select, :collection => [Author.find_by_login("justin"), Category.find_by_name("kate")] %>
98
100
  # <%= f.input :author, :as => :select, :collection => ["Justin", "Kate"] %>
99
101
  # <%= f.input :author, :as => :select, :collection => [["Justin", "justin"], ["Kate", "kate"]] %>
@@ -106,15 +108,6 @@ module Formtastic
106
108
  # <%= f.input :author, :as => :select, :collection => grouped_options_for_select(...) %>
107
109
  # <%= f.input :author, :as => :select, :collection => time_zone_options_for_select(...) %>
108
110
  #
109
- # @example The `:member_label` can be used to call a different method (or a Proc) on each object in the collection for rendering the label text (it'll try the methods like `to_s` in `collection_label_methods` config by default)
110
- # <%= f.input :author, :as => :select, :member_label => :name %>
111
- # <%= f.input :author, :as => :select, :member_label => :name_with_post_count %>
112
- # <%= f.input :author, :as => :select, :member_label => Proc.new { |a| "#{c.name} (#{pluralize("post", a.posts.count)})" } %>
113
- #
114
- # @example The `:member_value` can be used to call a different method (or a Proc) on each object in the collection for rendering the value for each checkbox (it'll try the methods like `id` in `collection_value_methods` config by default)
115
- # <%= f.input :author, :as => :select, :member_value => :login %>
116
- # <%= f.input :author, :as => :select, :member_value => Proc.new { |c| c.full_name.downcase.underscore } %>
117
- #
118
111
  # @example Set HTML attributes on the `<select>` tag with `:input_html`
119
112
  # <%= f.input :authors, :as => :select, :input_html => { :size => 20, :multiple => true, :class => "special" } %>
120
113
  #
@@ -1,3 +1,3 @@
1
1
  module Formtastic
2
- VERSION = "3.1.0.rc1"
2
+ VERSION = "3.1.0.rc2"
3
3
  end
@@ -350,9 +350,12 @@ describe 'check_boxes input' do
350
350
  item.stub(:custom_value).and_return('custom_value')
351
351
  item.should_receive(:custom_value).exactly(3).times
352
352
  @new_post.author.should_receive(:custom_value).exactly(1).times
353
- concat(semantic_form_for(@new_post) do |builder|
354
- concat(builder.input(:author, :as => :check_boxes, :member_value => :custom_value, :collection => [item, item, item]))
355
- end)
353
+
354
+ with_deprecation_silenced do
355
+ concat(semantic_form_for(@new_post) do |builder|
356
+ concat(builder.input(:author, :as => :check_boxes, :member_value => :custom_value, :collection => [item, item, item]))
357
+ end)
358
+ end
356
359
  output_buffer.should have_tag('input[@type=checkbox][@value="custom_value"]', :count => 3)
357
360
  end
358
361
  end
@@ -68,16 +68,20 @@ describe 'Formtastic::FormBuilder#label' do
68
68
 
69
69
  describe 'when a collection is given' do
70
70
  it 'should use a supplied label_method for simple collections' do
71
- concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
72
- concat(builder.input(:author_id, :as => :check_boxes, :collection => [:a, :b, :c], :member_value => :to_s, :member_label => proc {|f| ('Label_%s' % [f])}))
73
- end)
71
+ with_deprecation_silenced do
72
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
73
+ concat(builder.input(:author_id, :as => :check_boxes, :collection => [:a, :b, :c], :member_value => :to_s, :member_label => proc {|f| ('Label_%s' % [f])}))
74
+ end)
75
+ end
74
76
  output_buffer.should have_tag('form li fieldset ol li label', /Label_[abc]/, :count => 3)
75
77
  end
76
78
 
77
79
  it 'should use a supplied value_method for simple collections' do
78
- concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
79
- concat(builder.input(:author_id, :as => :check_boxes, :collection => [:a, :b, :c], :member_value => proc {|f| ('Value_%s' % [f.to_s])}))
80
- end)
80
+ with_deprecation_silenced do
81
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
82
+ concat(builder.input(:author_id, :as => :check_boxes, :collection => [:a, :b, :c], :member_value => proc {|f| ('Value_%s' % [f.to_s])}))
83
+ end)
84
+ end
81
85
  output_buffer.should have_tag('form li fieldset ol li label input[value="Value_a"]')
82
86
  output_buffer.should have_tag('form li fieldset ol li label input[value="Value_b"]')
83
87
  output_buffer.should have_tag('form li fieldset ol li label input[value="Value_c"]')
data/spec/spec_helper.rb CHANGED
@@ -534,7 +534,16 @@ RSpec.configure do |config|
534
534
  config.before(:each) do
535
535
  Formtastic::Localizer.cache.clear!
536
536
  end
537
-
537
+
538
+ config.before(:each) do
539
+ allow(Formtastic.deprecation).to receive(:deprecation_warning).and_call_original
540
+ # TODO: Remove this in Formtastic 4
541
+ [ :action_class, :standard_action_class_name, :custom_action_class_name,
542
+ :input_class, :standard_input_class_name, :custom_input_class_name ].each do |method|
543
+ allow(Formtastic.deprecation).to receive(:deprecation_warning).with(method, instance_of(String), instance_of(Array))
544
+ end
545
+ end
546
+
538
547
  config.before(:all) do
539
548
  DeferredGarbageCollection.start unless ENV["DEFER_GC"] == "false"
540
549
  end
@@ -428,9 +428,11 @@ module CustomMacros
428
428
 
429
429
  describe 'as a symbol' do
430
430
  before do
431
- concat(semantic_form_for(@new_post) do |builder|
432
- concat(builder.input(:author, :as => as, :member_label => :login))
433
- end)
431
+ with_deprecation_silenced do
432
+ concat(semantic_form_for(@new_post) do |builder|
433
+ concat(builder.input(:author, :as => as, :member_label => :login))
434
+ end)
435
+ end
434
436
  end
435
437
 
436
438
  it 'should have options with text content from the specified method' do
@@ -442,9 +444,11 @@ module CustomMacros
442
444
 
443
445
  describe 'as a proc' do
444
446
  before do
445
- concat(semantic_form_for(@new_post) do |builder|
446
- concat(builder.input(:author, :as => as, :member_label => Proc.new {|a| a.login.reverse }))
447
- end)
447
+ with_deprecation_silenced do
448
+ concat(semantic_form_for(@new_post) do |builder|
449
+ concat(builder.input(:author, :as => as, :member_label => Proc.new {|a| a.login.reverse }))
450
+ end)
451
+ end
448
452
  end
449
453
 
450
454
  it 'should have options with the proc applied to each' do
@@ -459,9 +463,11 @@ module CustomMacros
459
463
  def reverse_login(a)
460
464
  a.login.reverse
461
465
  end
462
- concat(semantic_form_for(@new_post) do |builder|
463
- concat(builder.input(:author, :as => as, :member_label => method(:reverse_login)))
464
- end)
466
+ with_deprecation_silenced do
467
+ concat(semantic_form_for(@new_post) do |builder|
468
+ concat(builder.input(:author, :as => as, :member_label => method(:reverse_login)))
469
+ end)
470
+ end
465
471
  end
466
472
 
467
473
  it 'should have options with the proc applied to each' do
@@ -480,9 +486,11 @@ module CustomMacros
480
486
  @fred.stub(:respond_to?) { |m| m.to_s == label_method || m.to_s == 'id' }
481
487
  [@fred, @bob].each { |a| a.stub(label_method).and_return('The Label Text') }
482
488
 
483
- concat(semantic_form_for(@new_post) do |builder|
484
- concat(builder.input(:author, :as => as))
485
- end)
489
+ with_deprecation_silenced do
490
+ concat(semantic_form_for(@new_post) do |builder|
491
+ concat(builder.input(:author, :as => as))
492
+ end)
493
+ end
486
494
  end
487
495
 
488
496
  it "should render the options with #{label_method} as the label" do
@@ -499,9 +507,11 @@ module CustomMacros
499
507
 
500
508
  describe 'as a symbol' do
501
509
  before do
502
- concat(semantic_form_for(@new_post) do |builder|
503
- concat(builder.input(:author, :as => as, :member_value => :login))
504
- end)
510
+ with_deprecation_silenced do
511
+ concat(semantic_form_for(@new_post) do |builder|
512
+ concat(builder.input(:author, :as => as, :member_value => :login))
513
+ end)
514
+ end
505
515
  end
506
516
 
507
517
  it 'should have options with values from specified method' do
@@ -513,9 +523,11 @@ module CustomMacros
513
523
 
514
524
  describe 'as a proc' do
515
525
  before do
516
- concat(semantic_form_for(@new_post) do |builder|
517
- concat(builder.input(:author, :as => as, :member_value => Proc.new {|a| a.login.reverse }))
518
- end)
526
+ with_deprecation_silenced do
527
+ concat(semantic_form_for(@new_post) do |builder|
528
+ concat(builder.input(:author, :as => as, :member_value => Proc.new {|a| a.login.reverse }))
529
+ end)
530
+ end
519
531
  end
520
532
 
521
533
  it 'should have options with the proc applied to each value' do
@@ -530,9 +542,11 @@ module CustomMacros
530
542
  def reverse_login(a)
531
543
  a.login.reverse
532
544
  end
533
- concat(semantic_form_for(@new_post) do |builder|
534
- concat(builder.input(:author, :as => as, :member_value => method(:reverse_login)))
535
- end)
545
+ with_deprecation_silenced do
546
+ concat(semantic_form_for(@new_post) do |builder|
547
+ concat(builder.input(:author, :as => as, :member_value => method(:reverse_login)))
548
+ end)
549
+ end
536
550
  end
537
551
 
538
552
  it 'should have options with the proc applied to each value' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: formtastic
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0.rc1
4
+ version: 3.1.0.rc2
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-11-04 00:00:00.000000000 Z
12
+ date: 2014-11-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack