formtastic 3.1.6 → 4.0.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.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +1 -0
  3. data/.gitignore +3 -2
  4. data/.travis.yml +28 -40
  5. data/CHANGELOG.md +49 -0
  6. data/DEPRECATIONS +1 -1
  7. data/Gemfile.lock +104 -0
  8. data/README.md +628 -629
  9. data/Rakefile +20 -1
  10. data/app/assets/stylesheets/formtastic.css +1 -1
  11. data/bin/appraisal +8 -0
  12. data/formtastic.gemspec +9 -14
  13. data/gemfiles/rails_5.2/Gemfile +5 -0
  14. data/gemfiles/rails_6.0/Gemfile +5 -0
  15. data/gemfiles/rails_edge/Gemfile +13 -0
  16. data/lib/formtastic/actions.rb +6 -3
  17. data/lib/formtastic/deprecation.rb +1 -38
  18. data/lib/formtastic/engine.rb +3 -1
  19. data/lib/formtastic/form_builder.rb +8 -24
  20. data/lib/formtastic/helpers/action_helper.rb +1 -48
  21. data/lib/formtastic/helpers/errors_helper.rb +2 -2
  22. data/lib/formtastic/helpers/fieldset_wrapper.rb +7 -3
  23. data/lib/formtastic/helpers/input_helper.rb +18 -76
  24. data/lib/formtastic/helpers/inputs_helper.rb +12 -3
  25. data/lib/formtastic/i18n.rb +1 -1
  26. data/lib/formtastic/inputs/base/collections.rb +1 -5
  27. data/lib/formtastic/inputs/base/errors.rb +4 -4
  28. data/lib/formtastic/inputs/base/hints.rb +1 -1
  29. data/lib/formtastic/inputs/base/timeish.rb +5 -1
  30. data/lib/formtastic/inputs/base/validations.rb +19 -9
  31. data/lib/formtastic/inputs/check_boxes_input.rb +3 -3
  32. data/lib/formtastic/inputs/color_input.rb +0 -1
  33. data/lib/formtastic/inputs/select_input.rb +1 -1
  34. data/lib/formtastic/inputs.rb +32 -29
  35. data/lib/formtastic/localizer.rb +4 -3
  36. data/lib/formtastic/version.rb +1 -1
  37. data/lib/formtastic.rb +5 -11
  38. data/lib/generators/templates/formtastic.rb +4 -6
  39. data/script/integration-template.rb +71 -0
  40. data/script/integration.sh +19 -0
  41. data/spec/action_class_finder_spec.rb +1 -1
  42. data/spec/actions/button_action_spec.rb +8 -8
  43. data/spec/actions/generic_action_spec.rb +60 -60
  44. data/spec/actions/input_action_spec.rb +7 -7
  45. data/spec/actions/link_action_spec.rb +10 -10
  46. data/spec/builder/custom_builder_spec.rb +36 -20
  47. data/spec/builder/error_proc_spec.rb +4 -4
  48. data/spec/builder/semantic_fields_for_spec.rb +27 -27
  49. data/spec/generators/formtastic/form/form_generator_spec.rb +25 -25
  50. data/spec/generators/formtastic/input/input_generator_spec.rb +31 -31
  51. data/spec/generators/formtastic/install/install_generator_spec.rb +9 -9
  52. data/spec/helpers/action_helper_spec.rb +328 -10
  53. data/spec/helpers/actions_helper_spec.rb +17 -17
  54. data/spec/helpers/form_helper_spec.rb +33 -33
  55. data/spec/helpers/input_helper_spec.rb +975 -2
  56. data/spec/helpers/inputs_helper_spec.rb +120 -105
  57. data/spec/helpers/reflection_helper_spec.rb +3 -3
  58. data/spec/helpers/semantic_errors_helper_spec.rb +22 -22
  59. data/spec/i18n_spec.rb +26 -26
  60. data/spec/input_class_finder_spec.rb +1 -1
  61. data/spec/inputs/base/collections_spec.rb +6 -6
  62. data/spec/inputs/base/validations_spec.rb +157 -19
  63. data/spec/inputs/boolean_input_spec.rb +55 -55
  64. data/spec/inputs/check_boxes_input_spec.rb +96 -95
  65. data/spec/inputs/color_input_spec.rb +51 -63
  66. data/spec/inputs/country_input_spec.rb +20 -20
  67. data/spec/inputs/custom_input_spec.rb +2 -6
  68. data/spec/inputs/datalist_input_spec.rb +1 -1
  69. data/spec/inputs/date_picker_input_spec.rb +42 -42
  70. data/spec/inputs/date_select_input_spec.rb +51 -37
  71. data/spec/inputs/datetime_picker_input_spec.rb +46 -46
  72. data/spec/inputs/datetime_select_input_spec.rb +53 -37
  73. data/spec/inputs/email_input_spec.rb +5 -5
  74. data/spec/inputs/file_input_spec.rb +6 -6
  75. data/spec/inputs/hidden_input_spec.rb +18 -18
  76. data/spec/inputs/include_blank_spec.rb +8 -8
  77. data/spec/inputs/label_spec.rb +20 -20
  78. data/spec/inputs/number_input_spec.rb +112 -112
  79. data/spec/inputs/password_input_spec.rb +5 -5
  80. data/spec/inputs/phone_input_spec.rb +5 -5
  81. data/spec/inputs/placeholder_spec.rb +5 -5
  82. data/spec/inputs/radio_input_spec.rb +63 -65
  83. data/spec/inputs/range_input_spec.rb +66 -66
  84. data/spec/inputs/readonly_spec.rb +4 -4
  85. data/spec/inputs/search_input_spec.rb +5 -5
  86. data/spec/inputs/select_input_spec.rb +92 -96
  87. data/spec/inputs/string_input_spec.rb +23 -23
  88. data/spec/inputs/text_input_spec.rb +16 -16
  89. data/spec/inputs/time_picker_input_spec.rb +43 -43
  90. data/spec/inputs/time_select_input_spec.rb +67 -54
  91. data/spec/inputs/time_zone_input_spec.rb +19 -19
  92. data/spec/inputs/url_input_spec.rb +5 -5
  93. data/spec/inputs/with_options_spec.rb +7 -7
  94. data/spec/localizer_spec.rb +17 -17
  95. data/spec/namespaced_class_finder_spec.rb +2 -2
  96. data/spec/schema.rb +21 -0
  97. data/spec/spec_helper.rb +163 -223
  98. data/spec/support/custom_macros.rb +72 -75
  99. data/spec/support/shared_examples.rb +0 -1301
  100. data/spec/support/test_environment.rb +23 -9
  101. metadata +36 -122
  102. data/Appraisals +0 -43
  103. data/CHANGELOG +0 -54
  104. data/gemfiles/rails_3.2.gemfile +0 -9
  105. data/gemfiles/rails_4.0.4.gemfile +0 -8
  106. data/gemfiles/rails_4.1.gemfile +0 -8
  107. data/gemfiles/rails_4.2.gemfile +0 -8
  108. data/gemfiles/rails_4.gemfile +0 -8
  109. data/gemfiles/rails_5.0.gemfile +0 -8
  110. data/gemfiles/rails_edge.gemfile +0 -15
  111. data/lib/formtastic/util.rb +0 -57
  112. data/spec/helpers/namespaced_action_helper_spec.rb +0 -43
  113. data/spec/helpers/namespaced_input_helper_spec.rb +0 -36
  114. data/spec/util_spec.rb +0 -66
data/Rakefile CHANGED
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  require 'bundler/setup'
3
- require 'appraisal'
4
3
  require 'yard'
5
4
  require 'rspec/core/rake_task'
6
5
 
@@ -13,6 +12,26 @@ else
13
12
  task :default => :spec
14
13
  end
15
14
 
15
+ desc 'Run the default task over all gemfiles.'
16
+ task :appraisal do
17
+ for_all_gemfiles("exec", "rake")
18
+ end
19
+
20
+ namespace :appraisal do
21
+ desc 'Run `bundle install` over all gemfiles.'
22
+ task :install do
23
+ for_all_gemfiles("install")
24
+ end
25
+ end
26
+
27
+ def for_all_gemfiles(*args)
28
+ Dir.glob("gemfiles/*/Gemfile").sort.each do |gemfile|
29
+ Bundler.with_original_env do
30
+ sh({ "APPRAISAL_INITIALIZED" => "true", "BUNDLE_GEMFILE" => gemfile }, "bundle", *args)
31
+ end
32
+ end
33
+ end
34
+
16
35
  desc 'Generate documentation for the formtastic plugin.'
17
36
  YARD::Rake::YardocTask.new(:yard) do |t|
18
37
 
@@ -223,7 +223,7 @@ This stylesheet forms part of the Formtastic Rails Plugin
223
223
  /* BOOLEAN LABELS
224
224
  --------------------------------------------------------------------------------------------------*/
225
225
  .formtastic .boolean label {
226
- padding-left:25%;
226
+ margin-left:25%;
227
227
  display:block;
228
228
  }
229
229
 
data/bin/appraisal ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+
3
+ if [ "$1" = "" ]
4
+ then
5
+ bundle exec rake appraisal
6
+ else
7
+ bundle exec rake "appraisal:$1"
8
+ fi
data/formtastic.gemspec CHANGED
@@ -15,27 +15,22 @@ Gem::Specification.new do |s|
15
15
 
16
16
  s.files = `git ls-files`.split("\n")
17
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.executables = []
19
19
  s.require_paths = ["lib"]
20
20
 
21
21
  s.rdoc_options = ["--charset=UTF-8"]
22
22
  s.extra_rdoc_files = ["README.md"]
23
23
 
24
- s.required_ruby_version = '>= 1.9.3'
24
+ s.required_ruby_version = '>= 2.4.0'
25
25
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
26
+ s.rubygems_version = %q{1.3.6}
26
27
 
27
- s.add_dependency(%q<actionpack>, [">= 3.2.13"])
28
+ s.add_dependency(%q<actionpack>, [">= 5.2.0"])
28
29
 
29
- s.add_development_dependency(%q<nokogiri>)
30
- s.add_development_dependency(%q<rspec-rails>, ["~> 3.3.2"])
31
- s.add_development_dependency(%q<rspec_tag_matchers>, ["~> 1.0"])
32
- s.add_development_dependency(%q<hpricot>, ["~> 0.8.3"])
33
- s.add_development_dependency(%q<RedCloth>, ["~> 4.2"]) # for YARD Textile formatting
34
- s.add_development_dependency(%q<yard>, ["~> 0.8"])
35
- s.add_development_dependency(%q<colored>, ["~> 1.2"])
36
- s.add_development_dependency(%q<tzinfo>)
30
+ s.add_development_dependency(%q<rspec-rails>, ["~> 3.4"])
31
+ s.add_development_dependency(%q<rspec-dom-testing>, [">= 0.1.0"])
32
+ s.add_development_dependency(%q<yard>, ["~> 0.9.20"])
37
33
  s.add_development_dependency(%q<ammeter>, ["~> 1.1.3"])
38
- s.add_development_dependency(%q<appraisal>, ["~> 2.1"])
39
- s.add_development_dependency(%q<rake>, ["< 12"])
40
- s.add_development_dependency(%q<activemodel>, [">= 3.2.13"])
34
+ s.add_development_dependency(%q<rake>)
35
+ s.add_development_dependency(%q<sqlite3>, ["~> 1.4"])
41
36
  end
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "rails", "~> 5.2.0"
4
+
5
+ gemspec path: "../.."
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "rails", "~> 6.0.2"
4
+
5
+ gemspec path: "../.."
@@ -0,0 +1,13 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "rails", git: "https://github.com/rails/rails.git"
4
+ gem "rack", git: "https://github.com/rack/rack.git"
5
+ gem "i18n", git: "https://github.com/svenfuchs/i18n.git"
6
+ gem "arel", git: "https://github.com/rails/arel.git"
7
+ gem "rspec-rails", git: "https://github.com/rspec/rspec-rails.git"
8
+ gem "rspec-mocks", git: "https://github.com/rspec/rspec-mocks.git"
9
+ gem "rspec-support", git: "https://github.com/rspec/rspec-support.git"
10
+ gem "rspec-core", git: "https://github.com/rspec/rspec-core.git"
11
+ gem "rspec-expectations", git: "https://github.com/rspec/rspec-expectations.git"
12
+
13
+ gemspec path: "../.."
@@ -4,8 +4,11 @@ module Formtastic
4
4
 
5
5
  autoload :Base
6
6
  autoload :Buttonish
7
- autoload :InputAction
8
- autoload :LinkAction
9
- autoload :ButtonAction
7
+
8
+ eager_autoload do
9
+ autoload :InputAction
10
+ autoload :LinkAction
11
+ autoload :ButtonAction
12
+ end
10
13
  end
11
14
  end
@@ -1,42 +1,5 @@
1
1
  require 'active_support/deprecation'
2
2
 
3
3
  module Formtastic
4
- if ActiveSupport::Deprecation.respond_to?(:new)
5
- Deprecation = ActiveSupport::Deprecation
6
- else
7
- require 'forwardable'
8
-
9
- # @private
10
- # @todo remove this branch and file when support for rails 3.2 is dropped
11
- class Deprecation
12
- mattr_accessor :deprecation
13
- self.deprecation = ActiveSupport::Deprecation.dup
14
-
15
- extend Forwardable
16
- methods = deprecation.methods - deprecation.class.methods
17
- def_delegators :deprecation, *methods
18
-
19
- def initialize(version, _library)
20
- deprecation.silenced = false
21
- deprecation.deprecation_horizon = version
22
- end
23
-
24
- def deprecation_warning(deprecated_method_name, message = nil, caller_backtrace = nil)
25
- caller_backtrace ||= caller(2)
26
-
27
- deprecated_method_warning(deprecated_method_name, message).tap do |msg|
28
- warn(msg, caller_backtrace)
29
- end
30
- end
31
-
32
- def deprecated_method_warning(method_name, message = nil)
33
- warning = "#{method_name} is deprecated and will be removed from Formtastic #{deprecation_horizon}"
34
- case message
35
- when Symbol then "#{warning} (use #{message} instead)"
36
- when String then "#{warning} (#{message})"
37
- else warning
38
- end
39
- end
40
- end
41
- end
4
+ Deprecation = ActiveSupport::Deprecation
42
5
  end
@@ -7,5 +7,7 @@ module Formtastic
7
7
  include Formtastic::Helpers::FormHelper
8
8
  end
9
9
  end
10
+
11
+ config.eager_load_namespaces << Formtastic
10
12
  end
11
- end
13
+ end
@@ -21,7 +21,7 @@ module Formtastic
21
21
  configure :default_text_area_width
22
22
  configure :all_fields_required_by_default, true
23
23
  configure :include_blank_for_select_by_default, true
24
- configure :required_string, proc { Formtastic::Util.html_safe(%{<abbr title="#{Formtastic::I18n.t(:required)}">*</abbr>}) }
24
+ configure :required_string, proc { %{<abbr title="#{Formtastic::I18n.t(:required)}">*</abbr>}.html_safe }
25
25
  configure :optional_string, ''
26
26
  configure :inline_errors, :sentence
27
27
  configure :label_str_method, :humanize
@@ -42,14 +42,10 @@ module Formtastic
42
42
  configure :perform_browser_validations, false
43
43
  # Check {Formtastic::InputClassFinder} to see how are inputs resolved.
44
44
  configure :input_namespaces, [::Object, ::Formtastic::Inputs]
45
- # @todo enable this as default in 4.0 and remove it from configuration generator template
46
- # Will be {Formtastic::InputClassFinder} by default in 4.0.
47
- configure :input_class_finder #, Formtastic::InputClassFinder
45
+ configure :input_class_finder, Formtastic::InputClassFinder
48
46
  # Check {Formtastic::ActionClassFinder} to see how are inputs resolved.
49
47
  configure :action_namespaces, [::Object, ::Formtastic::Actions]
50
- # @todo enable this as default in 4.0 and remove it from configuration generator template
51
- # Will be {Formtastic::ActionClassFinder} by default in 4.0.
52
- configure :action_class_finder#, Formtastic::ActionClassFinder
48
+ configure :action_class_finder, Formtastic::ActionClassFinder
53
49
 
54
50
  configure :skipped_columns, [:created_at, :updated_at, :created_on, :updated_on, :lock_version, :version]
55
51
  configure :priority_time_zones, []
@@ -68,8 +64,8 @@ module Formtastic
68
64
 
69
65
  # This is a wrapper around Rails' `ActionView::Helpers::FormBuilder#fields_for`, originally
70
66
  # provided to ensure that the `:builder` from `semantic_form_for` was passed down into
71
- # the nested `fields_for`. Rails 3 no longer requires us to do this, so this method is
72
- # provided purely for backwards compatibility and DSL consistency.
67
+ # the nested `fields_for`. Our supported versions of Rails no longer require us to do this,
68
+ # so this method is provided purely for backwards compatibility and DSL consistency.
73
69
  #
74
70
  # When constructing a `fields_for` form fragment *outside* of `semantic_form_for`, please use
75
71
  # `Formtastic::Helpers::FormHelper#semantic_fields_for`.
@@ -95,23 +91,11 @@ module Formtastic
95
91
  #
96
92
  # @todo is there a way to test the params structure of the Rails helper we wrap to ensure forward compatibility?
97
93
  def semantic_fields_for(record_or_name_or_array, *args, &block)
98
- # Add a :parent_builder to the args so that nested translations can be possible in Rails 3
99
- options = args.extract_options!
100
- options[:parent_builder] ||= self
101
-
102
- # Wrap the Rails helper
103
- fields_for(record_or_name_or_array, *(args << options), &block)
94
+ fields_for(record_or_name_or_array, *args, &block)
104
95
  end
105
96
 
106
- def initialize(object_name, object, template, options, block=nil)
107
- # rails 3 supported passing in the block parameter to FormBuilder
108
- # rails 4.0 deprecated the block parameter and does nothing with it
109
- # rails 4.1 removes the parameter completely
110
- if Util.rails3? || Util.rails4_0?
111
- super
112
- else # Must be rails4_1 or greater
113
- super object_name, object, template, options
114
- end
97
+ def initialize(object_name, object, template, options)
98
+ super
115
99
 
116
100
  if respond_to?('multipart=') && options.is_a?(Hash) && options[:html]
117
101
  self.multipart = options[:html][:multipart]
@@ -2,9 +2,6 @@
2
2
  module Formtastic
3
3
  module Helpers
4
4
  module ActionHelper
5
- ACTION_CLASS_DEPRECATION = 'configure Formtastic::FormBuilder.action_class_finder instead (upgrade guide on wiki: http://bit.ly/1F9QtKc )'.freeze
6
- private_constant(:ACTION_CLASS_DEPRECATION)
7
-
8
5
  # Renders an action for the form (such as a subit/reset button, or a cancel link).
9
6
  #
10
7
  # Each action is wrapped in an `<li class="action">` tag with other classes added based on the
@@ -82,7 +79,7 @@ module Formtastic
82
79
  options = options.dup # Allow options to be shared without being tainted by Formtastic
83
80
  options[:as] ||= default_action_type(method, options)
84
81
 
85
- klass = action_class(options[:as])
82
+ klass = namespaced_action_class(options[:as])
86
83
 
87
84
  klass.new(self, template, @object, @object_name, method, options).to_html
88
85
  end
@@ -113,50 +110,6 @@ module Formtastic
113
110
  rescue Formtastic::ActionClassFinder::NotFoundError => e
114
111
  raise Formtastic::UnknownActionError, "Unable to find action #{e.message}"
115
112
  end
116
-
117
- # @api private
118
- # @deprecated Use {#namespaced_action_class} instead.
119
- def action_class(as)
120
- return namespaced_action_class(as) if action_class_finder
121
-
122
- action_class_deprecation_warning(__method__)
123
-
124
- @input_classes_cache ||= {}
125
- @input_classes_cache[as] ||= begin
126
- begin
127
- begin
128
- custom_action_class_name(as).constantize
129
- rescue NameError
130
- standard_action_class_name(as).constantize
131
- end
132
- rescue NameError
133
- raise Formtastic::UnknownActionError, "Unable to find action #{as}"
134
- end
135
- end
136
- end
137
-
138
- # @api private
139
- # @deprecated Use {Formtastic::ActionClassFinder#class_name} instead.
140
- # :as => :button # => ButtonAction
141
- def custom_action_class_name(as)
142
- action_class_deprecation_warning(__method__)
143
- "#{as.to_s.camelize}Action"
144
- end
145
-
146
- # @api private
147
- # @deprecated Use {Formtastic::ActionClassFinder#class_name} instead.
148
- # :as => :button # => Formtastic::Actions::ButtonAction
149
- def standard_action_class_name(as)
150
- action_class_deprecation_warning(__method__)
151
- "Formtastic::Actions::#{as.to_s.camelize}Action"
152
- end
153
-
154
- private
155
-
156
- def action_class_deprecation_warning(method)
157
- @action_class_deprecation_warned ||=
158
- Formtastic.deprecation.deprecation_warning(method, ACTION_CLASS_DEPRECATION, caller(2))
159
- end
160
113
  end
161
114
  end
162
115
  end
@@ -52,7 +52,7 @@ module Formtastic
52
52
  return nil if full_errors.blank?
53
53
  html_options[:class] ||= "errors"
54
54
  template.content_tag(:ul, html_options) do
55
- Formtastic::Util.html_safe(full_errors.map { |error| template.content_tag(:li, Formtastic::Util.html_safe(error)) }.join)
55
+ full_errors.map { |error| template.content_tag(:li, error) }.join.html_safe
56
56
  end
57
57
  end
58
58
 
@@ -78,4 +78,4 @@ module Formtastic
78
78
  end
79
79
  end
80
80
  end
81
- end
81
+ end
@@ -33,12 +33,15 @@ module Formtastic
33
33
  end
34
34
  end
35
35
 
36
+ # Work-around for empty contents block
37
+ contents ||= ""
38
+
36
39
  # Ruby 1.9: String#to_s behavior changed, need to make an explicit join.
37
40
  contents = contents.join if contents.respond_to?(:join)
38
41
 
39
42
  legend = field_set_legend(html_options)
40
43
  fieldset = template.content_tag(:fieldset,
41
- Formtastic::Util.html_safe(legend) << template.content_tag(:ol, Formtastic::Util.html_safe(contents)),
44
+ legend.html_safe << template.content_tag(:ol, contents.html_safe),
42
45
  html_options.except(:builder, :parent, :name)
43
46
  )
44
47
 
@@ -47,8 +50,9 @@ module Formtastic
47
50
 
48
51
  def field_set_legend(html_options)
49
52
  legend = (html_options[:name] || '').to_s
50
- legend %= parent_child_index(html_options[:parent]) if html_options[:parent] && legend.include?('%i') # only applying if String includes '%i' avoids argument error when $DEBUG is true
51
- legend = template.content_tag(:legend, template.content_tag(:span, Formtastic::Util.html_safe(legend))) unless legend.blank?
53
+ # only applying if String includes '%i' avoids argument error when $DEBUG is true
54
+ legend %= parent_child_index(html_options[:parent]) if html_options[:parent] && legend.include?('%i')
55
+ legend = template.content_tag(:legend, template.content_tag(:span, legend.html_safe)) unless legend.blank?
52
56
  legend
53
57
  end
54
58
 
@@ -36,9 +36,6 @@ module Formtastic
36
36
  # @see Formtastic::Helpers::InputsHelper#inputs
37
37
  # @see Formtastic::Helpers::FormHelper#semantic_form_for
38
38
  module InputHelper
39
- INPUT_CLASS_DEPRECATION = 'configure Formtastic::FormBuilder.input_class_finder instead (upgrade guide on wiki: http://bit.ly/1F9QtKc )'.freeze
40
- private_constant(:INPUT_CLASS_DEPRECATION)
41
-
42
39
  include Formtastic::Helpers::Reflection
43
40
  include Formtastic::Helpers::Enum
44
41
  include Formtastic::Helpers::FileColumnDetection
@@ -237,7 +234,7 @@ module Formtastic
237
234
  options = options.dup # Allow options to be shared without being tainted by Formtastic
238
235
  options[:as] ||= default_input_type(method, options)
239
236
 
240
- klass = input_class(options[:as])
237
+ klass = namespaced_input_class(options[:as])
241
238
 
242
239
  klass.new(self, template, @object, @object_name, method, options).to_html
243
240
  end
@@ -286,6 +283,10 @@ module Formtastic
286
283
  return :time_select
287
284
  when :date
288
285
  return :date_select
286
+ when :hstore, :json, :jsonb
287
+ return :text
288
+ when :citext, :inet
289
+ return :string
289
290
  end
290
291
 
291
292
  # Try look for hints in options hash. Quite common senario: Enum keys stored as string in the database.
@@ -300,12 +301,20 @@ module Formtastic
300
301
  end
301
302
 
302
303
  # Get a column object for a specified attribute method - if possible.
304
+ # @return [ActiveModel::Type::Value, #type] in case of rails 5 attributes api
305
+ # @return [ActiveRecord::ConnectionAdapters::Column] in case of rails 4
303
306
  def column_for(method) # @private
304
- if @object.respond_to?(:column_for_attribute)
305
- # Remove deprecation wrapper & review after Rails 5.0 ships
306
- ActiveSupport::Deprecation.silence do
307
- @object.column_for_attribute(method)
308
- end
307
+ case
308
+ when @object.class.respond_to?(:type_for_attribute)
309
+ @object.class.type_for_attribute(method.to_s)
310
+ when @object.class.respond_to?(:column_for_attribute)
311
+ @object.class.column_for_attribute(method)
312
+ when @object.respond_to?(:column_for_attribute)
313
+ # Remove deprecation wrapper & review after Rails 5.0 ships
314
+ ActiveSupport::Deprecation.silence do
315
+ @object.column_for_attribute(method)
316
+ end
317
+ else nil
309
318
  end
310
319
  end
311
320
 
@@ -335,73 +344,6 @@ module Formtastic
335
344
  rescue Formtastic::InputClassFinder::NotFoundError
336
345
  raise Formtastic::UnknownInputError, "Unable to find input #{$!.message}"
337
346
  end
338
-
339
- # @api private
340
- # @deprecated Use {#namespaced_input_class} instead.
341
- def input_class(as)
342
- return namespaced_input_class(as) if input_class_finder
343
-
344
- input_class_deprecation_warning(__method__)
345
-
346
- @input_classes_cache ||= {}
347
- @input_classes_cache[as] ||= begin
348
- config = Rails.application.config
349
- use_const_defined = config.respond_to?(:eager_load) ? config.eager_load : config.cache_classes
350
- use_const_defined ? input_class_with_const_defined(as) : input_class_by_trying(as)
351
- end
352
- end
353
-
354
- # @api private
355
- # @deprecated Use {InputClassFinder#find} instead.
356
- # prevent exceptions in production environment for better performance
357
- def input_class_with_const_defined(as)
358
- input_class_name = custom_input_class_name(as)
359
-
360
- if ::Object.const_defined?(input_class_name)
361
- input_class_name.constantize
362
- elsif Formtastic::Inputs.const_defined?(input_class_name)
363
- standard_input_class_name(as).constantize
364
- else
365
- raise Formtastic::UnknownInputError, "Unable to find input class #{input_class_name}"
366
- end
367
- end
368
-
369
- # @api private
370
- # @deprecated Use {InputClassFinder#find} instead.
371
- # use auto-loading in development environment
372
- def input_class_by_trying(as)
373
- begin
374
- custom_input_class_name(as).constantize
375
- rescue NameError
376
- standard_input_class_name(as).constantize
377
- end
378
- rescue NameError
379
- raise Formtastic::UnknownInputError, "Unable to find input class for #{as}"
380
- end
381
-
382
- # @api private
383
- # @deprecated Use {InputClassFinder#class_name} instead.
384
- # :as => :string # => StringInput
385
- def custom_input_class_name(as)
386
- input_class_deprecation_warning(__method__)
387
- "#{as.to_s.camelize}Input"
388
- end
389
-
390
- # @api private
391
- # @deprecated Use {InputClassFinder#class_name} instead.
392
- # :as => :string # => {Formtastic::Inputs::StringInput}
393
- def standard_input_class_name(as)
394
- input_class_deprecation_warning(__method__)
395
- "Formtastic::Inputs::#{as.to_s.camelize}Input"
396
- end
397
-
398
- private
399
-
400
- def input_class_deprecation_warning(method)
401
- @input_class_deprecation_warned ||=
402
- Formtastic.deprecation.deprecation_warning(method, INPUT_CLASS_DEPRECATION, caller(2))
403
- end
404
-
405
347
  end
406
348
  end
407
349
  end
@@ -215,7 +215,7 @@ module Formtastic
215
215
  # <%= f.input :title ... %>
216
216
  # <%= f.input :body ... %>
217
217
  # <% end %>
218
- # <%= f.inputs do :name => 'Advanced options:' do %>
218
+ # <%= f.inputs :name => 'Advanced options:' do %>
219
219
  # <%= f.input :user ... %>
220
220
  # <%= f.input :categories ... %>
221
221
  # <% end %>
@@ -310,7 +310,7 @@ module Formtastic
310
310
  def default_columns_for_object
311
311
  cols = association_columns(:belongs_to)
312
312
  cols += content_columns
313
- cols -= Formtastic::FormBuilder.skipped_columns
313
+ cols -= skipped_columns
314
314
  cols.compact
315
315
  end
316
316
 
@@ -350,12 +350,21 @@ module Formtastic
350
350
  end
351
351
  end
352
352
 
353
+ # Collects all foreign key columns
354
+ def foreign_key_columns # @private
355
+ if @object.present? && @object.class.respond_to?(:reflect_on_all_associations)
356
+ @object.class.reflect_on_all_associations(:belongs_to).map(&:foreign_key)
357
+ else
358
+ []
359
+ end
360
+ end
361
+
353
362
  # Collects content columns (non-relation columns) for the current form object class.
354
363
  def content_columns # @private
355
364
  # TODO: NameError is raised by Inflector.constantize. Consider checking if it exists instead.
356
365
  begin klass = model_name.constantize; rescue NameError; return [] end
357
366
  return [] unless klass.respond_to?(:content_columns)
358
- klass.content_columns.collect { |c| c.name.to_sym }.compact
367
+ klass.content_columns.collect { |c| c.name.to_sym }.compact - foreign_key_columns
359
368
  end
360
369
 
361
370
  # Deals with :for option when it's supplied to inputs methods. Additional
@@ -23,7 +23,7 @@ module Formtastic
23
23
  options = args.extract_options!
24
24
  options.reverse_merge!(:default => DEFAULT_VALUES[key])
25
25
  options[:scope] = [DEFAULT_SCOPE, options[:scope]].flatten.compact
26
- ::I18n.translate(key, *(args << options))
26
+ ::I18n.translate(key, *args, **options)
27
27
  end
28
28
  alias :t :translate
29
29
 
@@ -84,11 +84,7 @@ module Formtastic
84
84
  scope_conditions = conditions_from_reflection.empty? ? nil : {:conditions => conditions_from_reflection}
85
85
  where_conditions = (scope_conditions && scope_conditions[:conditions]) || {}
86
86
 
87
- if Util.rails3?
88
- reflection.klass.scoped(scope_conditions).where({}) # where is uneccessary, but keeps the stubbing simpler while we support rails3
89
- else
90
- reflection.klass.where(where_conditions)
91
- end
87
+ reflection.klass.where(where_conditions)
92
88
  end
93
89
  end
94
90
 
@@ -9,21 +9,21 @@ module Formtastic
9
9
 
10
10
  def error_sentence_html
11
11
  error_class = builder.default_inline_error_class
12
- template.content_tag(:p, Formtastic::Util.html_safe(errors.to_sentence.html_safe), :class => error_class)
12
+ template.content_tag(:p, errors.to_sentence, :class => error_class)
13
13
  end
14
14
 
15
15
  def error_list_html
16
16
  error_class = builder.default_error_list_class
17
17
  list_elements = []
18
18
  errors.each do |error|
19
- list_elements << template.content_tag(:li, Formtastic::Util.html_safe(error.html_safe))
19
+ list_elements << template.content_tag(:li, error.html_safe)
20
20
  end
21
- template.content_tag(:ul, Formtastic::Util.html_safe(list_elements.join("\n")), :class => error_class)
21
+ template.content_tag(:ul, list_elements.join("\n").html_safe, :class => error_class)
22
22
  end
23
23
 
24
24
  def error_first_html
25
25
  error_class = builder.default_inline_error_class
26
- template.content_tag(:p, Formtastic::Util.html_safe(errors.first.untaint), :class => error_class)
26
+ template.content_tag(:p, errors.first.untaint.html_safe, :class => error_class)
27
27
  end
28
28
 
29
29
  def error_none_html
@@ -7,7 +7,7 @@ module Formtastic
7
7
  if hint?
8
8
  template.content_tag(
9
9
  :p,
10
- Formtastic::Util.html_safe(hint_text),
10
+ hint_text.html_safe,
11
11
  :class => builder.default_hint_class
12
12
  )
13
13
  end
@@ -85,6 +85,9 @@ module Formtastic
85
85
  # <%= f.input :publish_at, :as => :time_select, :include_blank => true %>
86
86
  # <%= f.input :publish_at, :as => :time_select, :include_blank => false %>
87
87
  #
88
+ # @example Provide a value for the field via selected
89
+ # <%= f.input :publish_at, :as => :datetime_select, :selected => DateTime.new(2018, 10, 4, 12, 00)
90
+ #
88
91
  # @todo Document i18n
89
92
  # @todo Check what other Rails options are supported (`start_year`, `end_year`, `use_month_numbers`, `use_short_month`, `add_month_numbers`, `prompt`), write tests for them, and otherwise support them
90
93
  # @todo Could we take the rendering from Rails' helpers and inject better HTML in and around it rather than re-inventing the whee?
@@ -157,6 +160,7 @@ module Formtastic
157
160
  end
158
161
 
159
162
  def value
163
+ return input_options[:selected] if options.key?(:selected)
160
164
  object.send(method) if object && object.respond_to?(method)
161
165
  end
162
166
 
@@ -238,4 +242,4 @@ module Formtastic
238
242
  end
239
243
  end
240
244
  end
241
- end
245
+ end