Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Removed deprecated options `:hint_class`, `:group_by`, `:group_label`, `:find_options` and `:value` #953

Closed
wants to merge 8 commits into from

4 participants

@justinfrench

Would love some review on this. Probably best to review commit-by-commit rather than a whole diff. Would particularly like review of 1fe253f, especially this line.

@sobrinho
Collaborator

Seems okay at first glance, I'm trusting on you travisci! :+1:

@twalpole
Collaborator

Should the configure option default_hint_class now be changed to hint_class, since theres no way to override it anymore? Same with default_inline_error_class and default_error_list_class

@twalpole

Does this actually need the .all ? or can it just be written as reflection.klass.where(scope_conditions) for all rails versions? - maybe its necessary for 3.0 or 3.1, been a while since I've worked with them, but I dont think its necessary for 3.2

Just checked the Rails 3.2 guides, you're right. If the Rails >= 3.2 branch goes in ahead of this (let's assume it does), this can be simpler. Thanks.

@twalpole
Collaborator

@justinfrench upon further review issue #954 affects the "remove deprecated :find_options option" and "refactor collection_from_association" changes. Summary -- rails4 got rid of the conditions option on associations and replaced it with a scope

has_many :somethings, conditions: { active: true }, ...
in rails 4 becomes
has_many :somethings, -> { where(active: true) }, ...
and the scope function is available on the reflection as scope. I think we should probably be handling this change.

@justinfrench

@twalpole great catch — how intertwined are these two issues? If the focus of this branch is removing old features (rather than adapting to Rails 4), can they be treated in isolation, or should we address #954 in here?

I'm also a little confused because in here you're using has_many in the example here (which we do need to handle) and Model.where in #954, which is still supported. I haven't had coffee yet though. Maybe it's a bad test that's confusing me because of the stubbing?

@justinfrench

@twalpole made a separate issue #955 for the configuration name — i suspect we have a few that don't make sense any more

@twalpole
Collaborator

@justinfrench I believe the has_many association in the model is reflected on to get the klass and then the :conditions option is applied to that class using where to get the collection - I may be confusing all of this, but thats my current understanding :). They can definitely be handled in isolation by removing the test for conditions options on assocations from rails 4 test runs, and then for rails 4 compatibility I think we need to handle the scope option now allowed on associations.

@pduersteler

:+1: for the work!

@justinfrench

Looks like this was achieved in another branch, closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
8 CHANGELOG
@@ -1,3 +1,11 @@
+master
+
+* Removed deprecated `:hint_class` option
+* Removed deprecated :group_by and :group_label options
+* Removed deprecated `:error_class` option
+* Removed deprecated `:find_options` option
+* Removed deprecated `:value` option from HiddenInput
+
2.3.0.rc2
* deprecate support for Rails < 3.2
View
8 lib/formtastic/inputs/base.rb
@@ -11,13 +11,6 @@ def initialize(builder, template, object, object_name, method, options)
@object_name = object_name
@method = method
@options = options.dup
-
- warn_deprecated_option!(:value, ":input_html => { :value => '...'}")
- warn_deprecated_option!(:hint_class, "default_hint_class configuration")
- warn_deprecated_option!(:error_class, "default_error_class configuration")
- warn_deprecated_option!(:group_by, ":collection option with a HTML string generated by Rails' grouped_options_for_select()")
- warn_deprecated_option!(:group_label, ":collection option with a HTML string generated by Rails' grouped_options_for_select()")
- warn_deprecated_option!(:find_options, "YourModel.find(...)")
end
# Usefull for deprecating options.
@@ -49,7 +42,6 @@ def removed_option!(old_option_name)
autoload :Database
autoload :Errors
autoload :Fileish
- autoload :GroupedCollections
autoload :Hints
autoload :Html
autoload :Labelling
View
4 lib/formtastic/inputs/base/associations.rb
@@ -12,6 +12,10 @@ def association
def reflection
@reflection ||= reflection_for(method)
end
+
+ def reflection_options?
+ reflection.respond_to?(:options)
+ end
def belongs_to?
association == :belongs_to
View
43 lib/formtastic/inputs/base/collections.rb
@@ -72,38 +72,25 @@ def collection_from_options
def collection_from_association
if reflection
- if reflection.respond_to?(:options)
+ if reflection_options? && reflection.options[:polymorphic] == true
raise PolymorphicInputWithoutCollectionError.new(
- "A collection must be supplied for #{method} input. Collections cannot be guessed for polymorphic associations."
- ) if reflection.options[:polymorphic] == true
- end
-
- find_options_from_options = options[:find_options] || {}
- conditions_from_options = find_options_from_options[:conditions] || {}
- conditions_from_reflection = (reflection.respond_to?(:options) && reflection.options[:conditions]) || {}
- conditions_from_reflection = conditions_from_reflection.call if conditions_from_reflection.is_a?(Proc)
-
- scope_conditions = conditions_from_reflection.empty? ? nil : {:conditions => conditions_from_reflection}
- if conditions_from_options.any?
- if Util.rails3?
- reflection.klass.scoped(scope_conditions).where(conditions_from_options)
- else
- reflection.klass.where(scope_conditions[:conditions]).where(conditions_from_options)
- end
- else
-
- if Util.rails3?
- find_options_from_options.merge!(:include => group_by) if self.respond_to?(:group_by) && group_by
- reflection.klass.scoped(scope_conditions).where(find_options_from_options)
- else
- coll = reflection.klass.where(scope_conditions)
- coll = coll.includes(group_by) if self.respond_to?(:group_by) && group_by
- coll.where(find_options_from_options)
- end
+ "A collection must be supplied for #{method} input. Collections cannot be guessed for polymorphic associations."
+ )
end
+ reflection.klass.where(conditions_from_scope)
end
end
-
+
+ def conditions_from_reflection
+ conditions = (reflection_options? && reflection.options[:conditions]) || {}
+ return conditions.call if conditions.is_a?(Proc)
+ return conditions
+ end
+
+ def conditions_from_scope
+ conditions_from_reflection.empty? ? nil : {:conditions => conditions_from_reflection}
+ end
+
def collection_for_boolean
true_text = options[:true] || Formtastic::I18n.t(:yes)
false_text = options[:false] || Formtastic::I18n.t(:no)
View
9 lib/formtastic/inputs/base/errors.rb
@@ -8,22 +8,19 @@ def error_html
end
def error_sentence_html
- error_class = options[:error_class] || builder.default_inline_error_class
- template.content_tag(:p, Formtastic::Util.html_safe(errors.to_sentence.html_safe), :class => error_class)
+ template.content_tag(:p, Formtastic::Util.html_safe(errors.to_sentence.html_safe), :class => builder.default_inline_error_class)
end
def error_list_html
- error_class = options[:error_class] || builder.default_error_list_class
list_elements = []
errors.each do |error|
list_elements << template.content_tag(:li, Formtastic::Util.html_safe(error.html_safe))
end
- template.content_tag(:ul, Formtastic::Util.html_safe(list_elements.join("\n")), :class => error_class)
+ template.content_tag(:ul, Formtastic::Util.html_safe(list_elements.join("\n")), :class => builder.default_error_list_class)
end
def error_first_html
- error_class = options[:error_class] || builder.default_inline_error_class
- template.content_tag(:p, Formtastic::Util.html_safe(errors.first.untaint), :class => error_class)
+ template.content_tag(:p, Formtastic::Util.html_safe(errors.first.untaint), :class => builder.default_inline_error_class)
end
def error_none_html
View
77 lib/formtastic/inputs/base/grouped_collections.rb
@@ -1,77 +0,0 @@
-module Formtastic
- module Inputs
- module Base
- module GroupedCollections
-
- def raw_grouped_collection
- @raw_grouped_collection ||= raw_collection.map { |option| option.send(options[:group_by]) }.uniq
- end
-
- def grouped_collection
- @grouped_collection ||= raw_grouped_collection.sort_by { |group_item| group_item.send(group_label_method) }
- end
-
- def group_label_method
- @group_label_method ||= (group_label_method_from_options || group_label_method_from_grouped_collection)
- end
-
- def group_label_method_from_options
- options[:group_label]
- end
-
- def group_label_method_from_grouped_collection
- label_and_value_method_from_collection(raw_grouped_collection).first
- end
-
- def group_association
- @group_association ||= (group_association_from_options || group_association_from_reflection)
- end
-
- def group_association_from_options
- options[:group_association]
- end
-
- def group_by
- options[:group_by]
- end
-
- def group_association_from_reflection
- method_to_group_association_by = reflection.klass.reflect_on_association(group_by)
- group_class = method_to_group_association_by.klass
-
- # This will return in the normal case
- return method.to_s.pluralize.to_sym if group_class.reflect_on_association(method.to_s.pluralize)
-
- # This is for belongs_to associations named differently than their class
- # form.input :parent, :group_by => :customer
- # eg.
- # class Project
- # belongs_to :parent, :class_name => 'Project', :foreign_key => 'parent_id'
- # belongs_to :customer
- # end
- # class Customer
- # has_many :projects
- # end
- group_method = group_class.to_s.underscore.pluralize.to_sym
- return group_method if group_class.reflect_on_association(group_method) # :projects
-
- # This is for has_many associations named differently than their class
- # eg.
- # class Project
- # belongs_to :parent, :class_name => 'Project', :foreign_key => 'parent_id'
- # belongs_to :customer
- # end
- # class Customer
- # has_many :tasks, :class_name => 'Project', :foreign_key => 'customer_id'
- # end
- possible_associations = group_class.reflect_on_all_associations(:has_many).find_all {|assoc| assoc.klass == reflection.klass }
- return possible_associations.first.name.to_sym if possible_associations.count == 1
-
- raise "Cannot infer group association for #{method} grouped by #{group_by}, there were #{possible_associations.empty? ? 'no' : possible_associations.size} possible associations. Please specify using :group_association"
- end
-
- end
- end
- end
-end
-
View
2  lib/formtastic/inputs/base/hints.rb
@@ -8,7 +8,7 @@ def hint_html
template.content_tag(
:p,
Formtastic::Util.html_safe(hint_text),
- :class => (options[:hint_class] || builder.default_hint_class)
+ :class => builder.default_hint_class
)
end
end
View
2  lib/formtastic/inputs/base/options.rb
@@ -8,7 +8,7 @@ def input_options
end
def formtastic_options
- [:priority_countries, :priority_zones, :member_label, :member_value, :collection, :required, :label, :as, :hint, :input_html, :value_as_class, :find_options, :class]
+ [:priority_countries, :priority_zones, :member_label, :member_value, :collection, :required, :label, :as, :hint, :input_html, :value_as_class, :class]
end
end
View
6 lib/formtastic/inputs/hidden_input.rb
@@ -31,12 +31,8 @@ module Inputs
class HiddenInput
include Base
- # Override to include :value set directly from options hash. The :value set in :input_html
- # hash will be preferred over :value set directly in the options.
- #
- # @deprecated :value option
def input_html_options
- options.slice(:value).merge(super).merge(:required => nil).merge(:autofocus => nil)
+ super.merge(:required => nil).merge(:autofocus => nil)
end
def to_html
View
16 lib/formtastic/inputs/select_input.rb
@@ -140,13 +140,12 @@ module Inputs
class SelectInput
include Base
include Base::Collections
- include Base::GroupedCollections
def to_html
input_wrapping do
hidden_input <<
label_html <<
- (options[:group_by] ? grouped_select_html : select_html)
+ select_html
end
end
@@ -154,19 +153,6 @@ def select_html
builder.select(input_name, collection, input_options, input_html_options)
end
- def grouped_select_html
- builder.grouped_collection_select(
- input_name,
- grouped_collection,
- group_association,
- group_label_method,
- value_method,
- label_method,
- input_options,
- input_html_options
- )
- end
-
def include_blank
options.key?(:include_blank) ? options[:include_blank] : (single? && builder.include_blank_for_select_by_default)
end
View
29 spec/helpers/input_helper_spec.rb
@@ -665,16 +665,6 @@ def length_should_be_required(options)
output_buffer.should have_tag("form li p.inline-hints", hint_text)
end
- it 'should have a custom hint class if I ask for one' do
- with_deprecation_silenced do
- hint_text = "this is the title of the post"
- concat(semantic_form_for(@new_post) do |builder|
- concat(builder.input(:title, :hint => hint_text, :hint_class => 'custom-hint-class'))
- end)
- output_buffer.should have_tag("form li p.custom-hint-class", hint_text)
- end
- end
-
it 'should have a custom hint class defaulted for all forms' do
hint_text = "this is the title of the post"
Formtastic::FormBuilder.default_hint_class = "custom-hint-class"
@@ -720,25 +710,6 @@ def length_should_be_required(options)
end
end
- it 'should render a hint paragraph containing a localized hint (I18n) with a custom hint class if i ask for one' do
- with_config :i18n_lookups_by_default, false do
- ::I18n.backend.store_translations :en,
- :formtastic => {
- :hints => {
- :post => {
- :title => @localized_hint_text
- }
- }
- }
- with_deprecation_silenced do
- concat(semantic_form_for(@new_post) do |builder|
- concat(builder.input(:title, :hint => true, :hint_class => 'custom-hint-class'))
- end)
- end
- output_buffer.should have_tag('form li p.custom-hint-class', @localized_hint_text)
- end
- end
-
it 'should render a hint paragraph containing an optional localized hint (I18n) if first is not set' do
with_config :i18n_lookups_by_default, false do
concat(semantic_form_for(@new_post) do |builder|
View
6 spec/inputs/hidden_input_spec.rb
@@ -12,7 +12,6 @@
with_deprecation_silenced do
concat(semantic_form_for(@new_post) do |builder|
concat(builder.input(:secret, :as => :hidden))
- concat(builder.input(:author_id, :as => :hidden, :value => 99))
concat(builder.input(:published, :as => :hidden, :input_html => {:value => true}))
concat(builder.input(:reviewer, :as => :hidden, :input_html => {:class => 'new_post_reviewer', :id => 'new_post_reviewer'}))
concat(builder.input(:author, :as => :hidden, :value => 'direct_value', :input_html => {:value => "formtastic_value"}))
@@ -35,11 +34,6 @@
output_buffer.should have_tag("form li input#post_secret[@type=\"hidden\"][@value=\"1\"]")
end
- it "should pass any explicitly specified value - using :value" do
- output_buffer.should have_tag("form li input#post_author_id[@type=\"hidden\"][@value=\"99\"]")
- end
-
- # Handle Formtastic :input_html options for consistency.
it "should pass any explicitly specified value - using :input_html options" do
output_buffer.should have_tag("form li input#post_published[@type=\"hidden\"][@value=\"true\"]")
end
View
10 spec/inputs/radio_input_spec.rb
@@ -97,16 +97,6 @@
output_buffer.should_not have_tag("form li fieldset ol li label input[@value='test'][@disabled='disabled']")
output_buffer.should have_tag("form li fieldset ol li label input[@value='try'][@disabled='disabled']")
end
-
- it "should not contain invalid HTML attributes" do
-
- concat(semantic_form_for(@new_post) do |builder|
- concat(builder.input(:author, :as => :radio))
- end)
-
- output_buffer.should_not have_tag("form li fieldset ol li input[@find_options]")
- end
-
end
describe 'and no object is given' do
View
112 spec/inputs/select_input_spec.rb
@@ -200,21 +200,6 @@
end
end
- describe "for a belongs_to association with :group_by => :author" do
- it "should call author.posts" do
- ::Author.stub!(:reflect_on_all_associations).and_return { |macro| macro == :has_many ? [mock('reflection', :klass => Post, :name => :posts)] : []}
-
- [@freds_post].each { |post| post.stub!(:to_label).and_return("Post - #{post.id}") }
- @fred.should_receive(:posts)
-
- with_deprecation_silenced do
- concat(semantic_form_for(@new_post) do |builder|
- concat(builder.input(:main_post, :as => :select, :group_by => :author ) )
- end)
- end
- end
- end
-
describe "for a belongs_to association with :conditions" do
before do
::Post.stub!(:reflect_on_association).with(:author).and_return do
@@ -235,103 +220,6 @@
concat(builder.input(:author, :as => :select))
end
end
-
- it "should call author.find with association conditions and find_options conditions" do
- if Formtastic::Util.rails3?
- ::Author.should_receive(:scoped).with(:conditions => {:active => true})
- ::Author.should_receive(:where).with({:publisher => true})
- else
- proxy = stub
- ::Author.should_receive(:where).with({:active => true}).and_return(proxy)
- proxy.should_receive(:where).with({:publisher => true})
- end
-
-
- with_deprecation_silenced do
- semantic_form_for(@new_post) do |builder|
- concat(builder.input(:author, :as => :select, :find_options => {:conditions => {:publisher => true}}))
- end
- end
- end
- end
-
- describe 'for a belongs_to association with :group_by => :continent' do
- before do
- @authors = [@bob, @fred, @fred, @fred]
- ::Author.stub!(:find).and_return(@authors)
- @continent_names = %w(Europe Africa)
- @continents = (0..1).map { |i| c = ::Continent.new; c.stub!(:id).and_return(100 - i);c }
- @authors[0..1].each_with_index { |author, i| author.stub!(:continent).and_return(@continents[i]) }
-
- ::Continent.stub!(:reflect_on_all_associations).and_return { |macro| macro == :has_many ? [mock('reflection', :klass => Author, :name => :authors)] : [] }
- ::Continent.stub!(:reflect_on_association).and_return {|column_name| mock('reflection', :klass => Author) if column_name == :authors}
- ::Author.stub!(:reflect_on_association).and_return { |column_name| mock('reflection', :options => {}, :klass => Continent, :macro => :belongs_to) if column_name == :continent }
-
-
- @continents.each_with_index do |continent, i|
- continent.stub!(:to_label).and_return(@continent_names[i])
- continent.stub!(:authors).and_return([@authors[i]])
- end
-
- with_deprecation_silenced do
- concat(semantic_form_for(@new_post) do |builder|
- concat(builder.input(:author, :as => :select, :group_by => :continent ) )
- concat(builder.input(:author, :as => :select, :group_by => :continent, :group_label => :id ) )
- concat(builder.input(:author, :as => :select, :group_by => :continent, :member_label => :login ) )
- concat(builder.input(:author, :as => :select, :group_by => :continent, :member_label => :login, :group_label => :id ) )
- end)
- end
- end
-
- it_should_have_input_wrapper_with_class("select")
- it_should_have_input_wrapper_with_id("post_author_input")
- it_should_have_label_with_text(/Author/)
- it_should_have_label_for('post_author_id')
-
- # TODO, need to find a way to repeat some of the specs and logic from the belongs_to specs without grouping
-
- 0.upto(1) do |i|
- it 'should have all option groups and the right values' do
- output_buffer.should have_tag("form li select optgroup[@label='#{@continent_names[i]}']", @authors[i].to_label)
- end
-
- it 'should have custom group labels' do
- output_buffer.should have_tag("form li select optgroup[@label='#{@continents[i].id}']", @authors[i].to_label)
- end
-
- it 'should have custom author labels' do
- output_buffer.should have_tag("form li select optgroup[@label='#{@continent_names[i]}']", @authors[i].login)
- end
-
- it 'should have custom author and group labels' do
- output_buffer.should have_tag("form li select optgroup[@label='#{@continents[i].id}']", @authors[i].login)
- end
- end
-
- it 'should have no duplicate groups' do
- output_buffer.should have_tag('form li select optgroup', :count => 8)
- end
-
- it 'should sort the groups on the label method' do
- output_buffer.should have_tag("form li select optgroup[@label='Africa']")
- output_buffer.should have_tag("form li select optgroup[@label='99']")
- end
-
- it 'should call find with :include for more optimized queries' do
- if Formtastic::Util.rails3?
- Author.should_receive(:where).with(:include => :continent)
- else
- proxy = author_array_or_scope(@authors)
- Author.should_receive(:where).and_return(proxy)
- proxy.should_receive(:includes).with(:continent).and_call_original
- end
-
- with_deprecation_silenced do
- semantic_form_for(@new_post) do |builder|
- concat(builder.input(:author, :as => :select, :group_by => :continent ) )
- end
- end
- end
end
describe 'for a has_many association' do
Something went wrong with that request. Please try again.