formtastic 2.3.0.rc2 → 2.3.0.rc3

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 (50) hide show
  1. data/.travis.yml +27 -1
  2. data/Appraisals +5 -0
  3. data/CHANGELOG +1 -0
  4. data/README.textile +19 -26
  5. data/formtastic.gemspec +4 -3
  6. data/gemfiles/rails_3.0.gemfile +1 -1
  7. data/gemfiles/rails_3.1.gemfile +1 -1
  8. data/gemfiles/rails_3.2.gemfile +1 -1
  9. data/gemfiles/rails_4.0.4.gemfile +7 -0
  10. data/gemfiles/rails_4.gemfile +1 -1
  11. data/lib/formtastic/form_builder.rb +9 -1
  12. data/lib/formtastic/helpers/form_helper.rb +11 -6
  13. data/lib/formtastic/helpers/inputs_helper.rb +6 -1
  14. data/lib/formtastic/inputs/base/collections.rb +1 -1
  15. data/lib/formtastic/inputs/base/validations.rb +1 -1
  16. data/lib/formtastic/inputs/boolean_input.rb +4 -14
  17. data/lib/formtastic/inputs/check_boxes_input.rb +7 -1
  18. data/lib/formtastic/inputs/radio_input.rb +2 -0
  19. data/lib/formtastic/util.rb +13 -1
  20. data/lib/formtastic/version.rb +1 -1
  21. data/lib/generators/templates/_form.html.slim +2 -2
  22. data/lib/generators/templates/formtastic.rb +15 -1
  23. data/spec/actions/generic_action_spec.rb +3 -3
  24. data/spec/builder/custom_builder_spec.rb +7 -7
  25. data/spec/builder/semantic_fields_for_spec.rb +8 -8
  26. data/spec/generators/formtastic/form/form_generator_spec.rb +6 -6
  27. data/spec/helpers/action_helper_spec.rb +11 -11
  28. data/spec/helpers/form_helper_spec.rb +22 -11
  29. data/spec/helpers/input_helper_spec.rb +44 -44
  30. data/spec/helpers/inputs_helper_spec.rb +64 -31
  31. data/spec/helpers/semantic_errors_helper_spec.rb +12 -12
  32. data/spec/i18n_spec.rb +5 -5
  33. data/spec/inputs/boolean_input_spec.rb +6 -5
  34. data/spec/inputs/check_boxes_input_spec.rb +27 -9
  35. data/spec/inputs/country_input_spec.rb +5 -5
  36. data/spec/inputs/custom_input_spec.rb +1 -1
  37. data/spec/inputs/date_picker_input_spec.rb +4 -4
  38. data/spec/inputs/datetime_picker_input_spec.rb +4 -4
  39. data/spec/inputs/hidden_input_spec.rb +3 -3
  40. data/spec/inputs/include_blank_spec.rb +2 -2
  41. data/spec/inputs/number_input_spec.rb +36 -36
  42. data/spec/inputs/radio_input_spec.rb +23 -5
  43. data/spec/inputs/range_input_spec.rb +19 -19
  44. data/spec/inputs/select_input_spec.rb +40 -20
  45. data/spec/inputs/string_input_spec.rb +2 -2
  46. data/spec/inputs/time_picker_input_spec.rb +4 -4
  47. data/spec/localizer_spec.rb +1 -1
  48. data/spec/spec_helper.rb +203 -188
  49. data/spec/support/custom_macros.rb +8 -8
  50. metadata +15 -13
data/.travis.yml CHANGED
@@ -1,4 +1,4 @@
1
- before_install:
1
+ before_install:
2
2
  - gem update --system
3
3
  - gem update bundler
4
4
  rvm:
@@ -6,6 +6,8 @@ rvm:
6
6
  - ree
7
7
  - 1.9.2
8
8
  - 1.9.3
9
+ - 2.0.0
10
+ - 2.1.0
9
11
  gemfile:
10
12
  - gemfiles/rails_3.0.gemfile
11
13
  - gemfiles/rails_3.1.gemfile
@@ -21,6 +23,24 @@ matrix:
21
23
  - rvm: 2.0.0
22
24
  gemfile: gemfiles/rails_4.gemfile
23
25
  env: DEFER_GC=false RAILS_EDGE=true
26
+ - rvm: 2.1.0
27
+ gemfile: gemfiles/rails_4.gemfile
28
+ env: DEFER_GC=false RAILS_EDGE=true
29
+ - rvm: 1.9.3
30
+ gemfile: gemfiles/rails_4.0.4.gemfile
31
+ env: DEFER_GC=false RAILS_EDGE=true
32
+ - rvm: 2.0.0
33
+ gemfile: gemfiles/rails_4.0.4.gemfile
34
+ env: DEFER_GC=false RAILS_EDGE=true
35
+ - rvm: 1.9.3
36
+ gemfile: gemfiles/rails_edge.gemfile
37
+ env: DEFER_GC=false RAILS_EDGE=true
38
+ - rvm: 2.0.0
39
+ gemfile: gemfiles/rails_edge.gemfile
40
+ env: DEFER_GC=false RAILS_EDGE=true
41
+ - rvm: 2.1.0
42
+ gemfile: gemfiles/rails_edge.gemfile
43
+ env: DEFER_GC=false RAILS_EDGE=true
24
44
  allow_failures:
25
45
  - rvm: 1.9.3
26
46
  gemfile: gemfiles/rails_edge.gemfile
@@ -28,3 +48,9 @@ matrix:
28
48
  - rvm: 2.0.0
29
49
  gemfile: gemfiles/rails_edge.gemfile
30
50
  env: DEFER_GC=false RAILS_EDGE=true
51
+ - rvm: 2.1.0
52
+ gemfile: gemfiles/rails_4.gemfile
53
+ env: DEFER_GC=false RAILS_EDGE=true
54
+ - rvm: 2.1.0
55
+ gemfile: gemfiles/rails_edge.gemfile
56
+ env: DEFER_GC=false RAILS_EDGE=true
data/Appraisals CHANGED
@@ -14,6 +14,11 @@ appraise 'rails-4' do
14
14
  gem 'rails', '~> 4.0.0'
15
15
  end
16
16
 
17
+ # Special case for a change in I18n
18
+ appraise 'rails-4.0.4' do
19
+ gem 'rails', '4.0.4'
20
+ end
21
+
17
22
  if ENV["RAILS_EDGE"] == "true"
18
23
  appraise 'rails-edge' do
19
24
  gem 'rails', :git => 'git://github.com/rails/rails.git'
data/CHANGELOG CHANGED
@@ -1,6 +1,7 @@
1
1
  2.3.0.rc2
2
2
 
3
3
  * deprecate support for Rails < 3.2
4
+ * avoid clobbering `ActionView::Base.field_error_proc=` by using a custom class attribute: `Formtastic::Helpers::FormHelper.formtastic_field_error_proc=`.
4
5
 
5
6
  2.3.0.rc
6
7
 
data/README.textile CHANGED
@@ -1,8 +1,12 @@
1
1
  h1. Formtastic
2
2
 
3
- Formtastic is a Rails FormBuilder DSL (with some other goodies) to make it far easier to create beautiful, semantically rich, syntactically awesome, readily stylable and wonderfully accessible HTML forms in your Rails applications.
3
+ !https://travis-ci.org/justinfrench/formtastic.png?branch=master!:https://travis-ci.org/justinfrench/formtastic
4
+ !http://inch-pages.github.io/github/justinfrench/formtastic.png!:http://inch-pages.github.io/github/justinfrench/formtastic
5
+ !https://codeclimate.com/github/justinfrench/formtastic.png!:https://codeclimate.com/github/justinfrench/formtastic
6
+ !https://badge.fury.io/rb/formtastic.png!:http://badge.fury.io/rb/formtastic
7
+ !https://gemnasium.com/justinfrench/formtastic.png!:https://gemnasium.com/justinfrench/formtastic
4
8
 
5
- <a href='http://www.pledgie.com/campaigns/2178'><img alt='Click here to lend your support to: formtastic and make a donation at www.pledgie.com !' src='http://pledgie.com/campaigns/2178.png?skin_name=chrome' border='0' /></a>
9
+ Formtastic is a Rails FormBuilder DSL (with some other goodies) to make it far easier to create beautiful, semantically rich, syntactically awesome, readily stylable and wonderfully accessible HTML forms in your Rails applications.
6
10
 
7
11
 
8
12
  h2. Documentation & Support
@@ -20,7 +24,7 @@ h2. Compatibility
20
24
  * Formtastic 2.3 is Rails 3 and Rails 4 compatible (Rails < 3.2 is deprecated)
21
25
  * Formtastic 2.1 & 2.2 is Rails 3 and Rails 4 compatible
22
26
  * Formtastic, much like Rails, is very ActiveRecord-centric. Many are successfully using other ActiveModel-like ORMs and objects (DataMapper, MongoMapper, Mongoid, Authlogic, Devise...) but we're not guaranteeing full compatibility at this stage. Patches are welcome!
23
-
27
+
24
28
 
25
29
  h2. The Story
26
30
 
@@ -95,7 +99,7 @@ Simply add Formtastic to your Gemfile and bundle it up:
95
99
  Run the installation generator:
96
100
 
97
101
  <pre>
98
- $ rails generate formtastic:install
102
+ $ rails generate formtastic:install
99
103
  </pre>
100
104
 
101
105
 
@@ -106,7 +110,7 @@ A proof-of-concept set of stylesheets are provided which you can include in your
106
110
  h3. Stylesheet usage in Rails < 3.1:
107
111
 
108
112
  <pre>
109
- $ rails generate formtastic:install
113
+ $ rails generate formtastic:install
110
114
  </pre>
111
115
 
112
116
  <pre>
@@ -131,7 +135,7 @@ Conditional stylesheets need to be compiled separately to prevent them being bun
131
135
  <pre>
132
136
  # app/assets/stylesheets/ie6.css
133
137
  *= require formtastic_ie6
134
-
138
+
135
139
  # app/assets/stylesheets/ie7.css
136
140
  *= require formtastic_ie7
137
141
  </pre>
@@ -145,7 +149,7 @@ Conditional stylesheets need to be compiled separately to prevent them being bun
145
149
 
146
150
  <pre>
147
151
  # config/environments/production.rb
148
- config.assets.precompile += %w( ie6.css ie7.css )
152
+ config.assets.precompile += %w( ie6.css ie7.css )
149
153
  </pre>
150
154
 
151
155
  h2. Usage
@@ -365,7 +369,7 @@ Formtastic decides which label to use in the following order:
365
369
  1. :label # :label => "Choose Title"
366
370
  2. Formtastic i18n # if either :label => true || i18n_lookups_by_default = true (see Internationalization)
367
371
  3. Activerecord i18n # if localization file found for the given attribute
368
- 4. label_str_method # if nothing provided this defaults to :humanize but can be set to a custom method
372
+ 4. label_str_method # if nothing provided this defaults to :humanize but can be set to a custom method
369
373
  </pre>
370
374
 
371
375
  h2. Internationalization (I18n)
@@ -398,7 +402,7 @@ Formtastic supports localized *labels*, *hints*, *legends*, *actions* using the
398
402
  Formtastic::FormBuilder.i18n_lookups_by_default = true
399
403
  </pre>
400
404
 
401
- *2. Add some cool label-translations/variants (@config/locale/en.yml@):*
405
+ *2. Add some label-translations/variants (@config/locales/en.yml@):*
402
406
 
403
407
  <pre>
404
408
  en:
@@ -593,39 +597,28 @@ To create a custom @DatePickerInput@ from scratch, put the following in @app/inp
593
597
 
594
598
  You can use your new input with @:as => :date_picker@.
595
599
 
596
- h3. Don't subclass Formtastic::FormBuilder anymore
597
-
598
- It was previously recommended in Formtastic 1.x to subclass Formtastic::FormBuilder to add your own inputs. This is no longer recommended in Formtastic 2, and will not work as expected.
599
-
600
-
601
- h2. Security
602
-
603
- By default, Formtastic escapes HTML entities in both labels and hints unless a string is marked as html_safe. If you are using an older rails version which doesn't know html_safe, or you want to globally turn this feature off, you can set the following in your initializer:
604
-
605
- Formtastic::FormBuilder.escape_html_entities_in_hints_and_labels = false
606
-
607
600
 
608
601
  h2. Dependencies
609
602
 
610
603
  There are none other than Rails itself, but...
611
604
 
612
- * If you want to use the @:country@ input, you'll need to install the "country-select plugin":https://github.com/chrislerum/country_select (or any other country_select plugin with the same API).
613
- * There are a bunch of development dependencies
605
+ * If you want to use the @:country@ input, you'll need to install the "country-select plugin":https://github.com/stefanpenner/country_select (or any other country_select plugin with the same API).
606
+ * There are a bunch of development dependencies if you plan to contribute to Formtastic
614
607
 
615
608
 
616
609
  h2. How to contribute
617
610
 
618
611
  * Fork the project on Github
619
612
  * Create a topic branch for your changes
620
- * Ensure that you provide test coverage for your changes
613
+ * Ensure that you provide *documentation* and *test coverage* for your changes (patches won't be accepted without)
621
614
  * Ensure that all tests pass (`bundle exec rake`)
622
- * Create a pull request on Github
615
+ * Create a pull request on Github (these are also a great place to start a conversation around a patch as early as possible)
623
616
 
624
617
 
625
618
  h2. Project Info
626
619
 
627
- Formtastic was created by "Justin French":http://www.justinfrench.com with contributions from around 150 awesome developers. Run @git shortlog -n -s@ to see the awesome.
620
+ Formtastic was created by "Justin French":http://www.justinfrench.com with contributions from around 180 awesome developers. Run @git shortlog -n -s@ to see the awesome.
628
621
 
629
622
  The project is hosted on Github: "http://github.com/justinfrench/formtastic":http://github.com/justinfrench/formtastic, where your contributions, forkings, comments, issues and feedback are greatly welcomed.
630
623
 
631
- Copyright (c) 2007-2012 Justin French, released under the MIT license.
624
+ Copyright (c) 2007-2014 Justin French, released under the MIT license.
data/formtastic.gemspec CHANGED
@@ -11,6 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.homepage = %q{http://github.com/justinfrench/formtastic}
12
12
  s.summary = %q{A Rails form builder plugin/gem with semantically rich and accessible markup}
13
13
  s.description = %q{A Rails form builder plugin/gem with semantically rich and accessible markup}
14
+ s.license = 'MIT'
14
15
 
15
16
  s.files = `git ls-files`.split("\n")
16
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -26,7 +27,7 @@ Gem::Specification.new do |s|
26
27
  s.add_dependency(%q<actionpack>, [">= 3.0"])
27
28
 
28
29
  s.add_development_dependency(%q<nokogiri>, ["< 1.6.0"]) # 1.6 requires Ruby 1.9.2, drop in v3.0
29
- s.add_development_dependency(%q<rspec-rails>, ["~> 2.12.0"])
30
+ s.add_development_dependency(%q<rspec-rails>, ["~> 2.14.0"])
30
31
  s.add_development_dependency(%q<rspec_tag_matchers>, [">= 1.0.0"])
31
32
  s.add_development_dependency(%q<hpricot>, ["~> 0.8.3"])
32
33
  s.add_development_dependency(%q<BlueCloth>) # for YARD
@@ -34,7 +35,7 @@ Gem::Specification.new do |s|
34
35
  s.add_development_dependency(%q<colored>)
35
36
  s.add_development_dependency(%q<tzinfo>)
36
37
  s.add_development_dependency(%q<ammeter>, ["0.2.5"])
37
- s.add_development_dependency(%q<appraisal>)
38
- s.add_development_dependency(%q<rake>)
38
+ s.add_development_dependency(%q<appraisal>, ["1.0.0.beta3"])
39
+ s.add_development_dependency(%q<rake>, ["<= 10.1.1"]) # Anything higher requires Ruby 1.9, drop in v3.0
39
40
  s.add_development_dependency(%q<activemodel>)
40
41
  end
@@ -4,4 +4,4 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "rails", "~> 3.0.0"
6
6
 
7
- gemspec :path=>"../"
7
+ gemspec :path=>".././"
@@ -4,4 +4,4 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "rails", "~> 3.1.0"
6
6
 
7
- gemspec :path=>"../"
7
+ gemspec :path=>".././"
@@ -4,4 +4,4 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "rails", "~> 3.2.0"
6
6
 
7
- gemspec :path=>"../"
7
+ gemspec :path=>".././"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "4.0.4"
6
+
7
+ gemspec :path=>".././"
@@ -4,4 +4,4 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "rails", "~> 4.0.0"
6
6
 
7
- gemspec :path=>"../"
7
+ gemspec :path=>".././"
@@ -82,7 +82,15 @@ module Formtastic
82
82
  end
83
83
 
84
84
  def initialize(object_name, object, template, options, block=nil)
85
- super
85
+ # rails 3 supported passing in the block parameter to FormBuilder
86
+ # rails 4.0 deprecated the block parameter and does nothing with it
87
+ # rails 4.1 removes the parameter completely
88
+ if Util.rails3? || Util.rails4_0?
89
+ super
90
+ else # Must be rails4_1 or greater
91
+ super object_name, object, template, options
92
+ end
93
+
86
94
  if respond_to?('multipart=') && options.is_a?(Hash) && options[:html]
87
95
  self.multipart = options[:html][:multipart]
88
96
  end
@@ -58,11 +58,16 @@ module Formtastic
58
58
  @@default_form_class = 'formtastic'
59
59
  mattr_accessor :default_form_class
60
60
 
61
+ # Allows to set a custom proc to handle the class infered from the model's name. By default it
62
+ # will infer the name from the class name (eg. Post will be "post").
63
+ @@default_form_model_class_proc = proc { |model_class_name| model_class_name }
64
+ mattr_accessor :default_form_model_class_proc
65
+
61
66
  # Allows to set a custom field_error_proc wrapper. By default this wrapper
62
67
  # is disabled since `formtastic` already adds an error class to the LI tag
63
68
  # containing the input. Change this from `config/initializers/formtastic.rb`.
64
- @@field_error_proc = proc { |html_tag, instance_tag| html_tag }
65
- mattr_accessor :field_error_proc
69
+ @@formtastic_field_error_proc = proc { |html_tag, instance_tag| html_tag }
70
+ mattr_accessor :formtastic_field_error_proc
66
71
 
67
72
  # Wrapper around Rails' own `form_for` helper to set the `:builder` option to
68
73
  # `Formtastic::FormBuilder` and to set some class names on the `<form>` tag such as
@@ -156,11 +161,13 @@ module Formtastic
156
161
 
157
162
  class_names = options[:html][:class] ? options[:html][:class].split(" ") : []
158
163
  class_names << @@default_form_class
159
- class_names << case record_or_name_or_array
164
+ model_class_name = case record_or_name_or_array
160
165
  when String, Symbol then record_or_name_or_array.to_s # :post => "post"
161
166
  when Array then options[:as] || singularizer.call(record_or_name_or_array.last.class) # [@post, @comment] # => "comment"
162
167
  else options[:as] || singularizer.call(record_or_name_or_array.class) # @post => "post"
163
168
  end
169
+ class_names << @@default_form_model_class_proc.call(model_class_name)
170
+
164
171
  options[:html][:class] = class_names.compact.join(" ")
165
172
 
166
173
  with_custom_field_error_proc do
@@ -186,13 +193,11 @@ module Formtastic
186
193
 
187
194
  def with_custom_field_error_proc(&block)
188
195
  default_field_error_proc = ::ActionView::Base.field_error_proc
189
- ::ActionView::Base.field_error_proc = @@field_error_proc
196
+ ::ActionView::Base.field_error_proc = @@formtastic_field_error_proc
190
197
  yield
191
198
  ensure
192
199
  ::ActionView::Base.field_error_proc = default_field_error_proc
193
200
  end
194
-
195
-
196
201
  end
197
202
  end
198
203
  end
@@ -182,6 +182,10 @@ module Formtastic
182
182
  # <%= f.inputs %>
183
183
  # <% end %>
184
184
  #
185
+ # @example Quick form: Skip one or more fields
186
+ # <%= f.inputs, :except => [:featured, :something_for_admin_only] %>
187
+ # <%= f.inputs, :except => :featured %>
188
+ #
185
189
  # @example Short hand: Render inputs for a named set of attributes and simple associations on the model, with all default arguments and options
186
190
  # <% semantic_form_for @post do |form| %>
187
191
  # <%= f.inputs, :title, :body, :user, :categories %>
@@ -284,6 +288,7 @@ module Formtastic
284
288
  html_options = args.extract_options!
285
289
  html_options[:class] ||= "inputs"
286
290
  html_options[:name] = title
291
+ skipped_args = Array.wrap html_options.delete(:except)
287
292
 
288
293
  out = begin
289
294
  if html_options[:for] # Nested form
@@ -292,7 +297,7 @@ module Formtastic
292
297
  field_set_and_list_wrapping(*(args << html_options), &block)
293
298
  else
294
299
  legend = args.shift if args.first.is_a?(::String)
295
- args = default_columns_for_object if @object && args.empty?
300
+ args = default_columns_for_object - skipped_args if @object && args.empty?
296
301
  contents = fieldset_contents_from_column_list(args)
297
302
  args.unshift(legend) if legend.present?
298
303
  field_set_and_list_wrapping(*((args << html_options) << contents))
@@ -124,7 +124,7 @@ module Formtastic
124
124
  # Avoids an issue where `send_or_call` can be a String and duck can be something simple like
125
125
  # `:first`, which obviously String responds to.
126
126
  def send_or_call_or_object(duck, object)
127
- return object if object.is_a?(String) || object.is_a?(Integer) # TODO what about other classes etc?
127
+ return object if object.is_a?(String) || object.is_a?(Integer) || object.is_a?(Symbol) # TODO what about other classes etc?
128
128
  send_or_call(duck, object)
129
129
  end
130
130
 
@@ -35,7 +35,7 @@ module Formtastic
35
35
  return true unless validator.options.key?(:if) || validator.options.key?(:unless)
36
36
  conditional = validator.options.key?(:if) ? validator.options[:if] : validator.options[:unless]
37
37
 
38
- result = if conditional.respond_to?(:call)
38
+ result = if conditional.respond_to?(:call) && conditional.arity > 0
39
39
  conditional.call(object)
40
40
  elsif conditional.is_a?(::Symbol) && object.respond_to?(conditional)
41
41
  object.send(conditional)
@@ -51,21 +51,11 @@ module Formtastic
51
51
  )
52
52
  end
53
53
 
54
- # TODO: why are we merging `input_html_options` and then making some of the irrelevant ones `nil`?
55
- # Seems like we should be selectively including from input_html_options (a whitelist) instead of
56
- # excluding (blacklist).
57
54
  def label_html_options
58
- prev = super
59
- prev[:class] = prev[:class] - ['label']
60
-
61
- input_html_options.merge(
62
- prev.merge(
63
- :id => nil,
64
- :name => nil,
65
- :tabindex => nil,
66
- :for => input_html_options[:id]
67
- )
68
- )
55
+ {
56
+ :for => input_html_options[:id],
57
+ :class => super[:class] - ['label'] # remove 'label' class
58
+ }
69
59
  end
70
60
 
71
61
  def label_text_with_embedded_checkbox
@@ -46,6 +46,9 @@ module Formtastic
46
46
  # <%= f.input :categories, :as => :check_boxes, :collection => [["Ruby", 1], ["Rails", 2]] %>
47
47
  # <%= f.input :categories, :as => :check_boxes, :collection => [["Ruby", 1, {'data-attr' => 'attr-value'}]] %>
48
48
  # <%= f.input :categories, :as => :check_boxes, :collection => 1..5 %>
49
+ # <%= f.input :categories, :as => :check_boxes, :collection => [:ruby, :rails] %>
50
+ # <%= f.input :categories, :as => :check_boxes, :collection => [["Ruby", :ruby], ["Rails", :rails]] %>
51
+ # <%= f.input :categories, :as => :check_boxes, :collection => Set.new([:ruby, :rails]) %>
49
52
  #
50
53
  # @example `:hidden_fields` can be used to skip Rails' rendering of a hidden field before every checkbox
51
54
  # <%= f.input :categories, :as => :check_boxes, :hidden_fields => false %>
@@ -182,7 +185,10 @@ module Formtastic
182
185
 
183
186
  def make_selected_values
184
187
  if object.respond_to?(method)
185
- selected_items = [object.send(method)].compact.flatten
188
+ selected_items = object.send(method)
189
+
190
+ # Construct an array from the return value, regardless of the return type
191
+ selected_items = [*selected_items].compact.flatten
186
192
 
187
193
  [*selected_items.map { |o| send_or_call_or_object(value_method, o) }].compact
188
194
  else
@@ -83,6 +83,8 @@ module Formtastic
83
83
  # <%= f.input :author, :as => :radio, :collection => [["Justin", "justin"], ["Kate", "kate"]] %>
84
84
  # <%= f.input :author, :as => :radio, :collection => [["Justin", "1"], ["Kate", "3"]] %>
85
85
  # <%= f.input :author, :as => :radio, :collection => [["Justin", 1], ["Kate", 3]] %>
86
+ # <%= f.input :author, :as => :radio, :collection => [["Justin", :justin], ["Kate", :kate]] %>
87
+ # <%= f.input :author, :as => :radio, :collection => [:justin, :kate] %>
86
88
  # <%= f.input :author, :as => :radio, :collection => 1..5 %>
87
89
  #
88
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)
@@ -24,9 +24,21 @@ module Formtastic
24
24
  def rails3?
25
25
  ::Rails::VERSION::MAJOR == 3
26
26
  end
27
+
28
+ def rails4?
29
+ ::Rails::VERSION::MAJOR == 4
30
+ end
31
+
32
+ def rails4_0?
33
+ ::Rails::VERSION::MAJOR == 4 && ::Rails::VERSION::MINOR == 0
34
+ end
35
+
36
+ def rails4_1?
37
+ ::Rails::VERSION::MAJOR == 4 && ::Rails::VERSION::MINOR == 1
38
+ end
27
39
 
28
40
  def deprecated_version_of_rails?
29
- const_defined?(:Rails) && ::Rails::VERSION::MAJOR == 3 && ::Rails::VERSION::MINOR < 2
41
+ const_defined?(:Rails) && ::Rails::VERSION::MAJOR == 3 && ::Rails::VERSION::MINOR < 2 && ::Rails::VERSION::PATCH < 13
30
42
  end
31
43
 
32
44
  end