From 28f8a9b3b9538357b65da1b71b486c9cb020dfc1 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Thu, 10 Dec 2009 11:57:05 -0200 Subject: [PATCH] Refactoring attribute column, apply html options and start work on string options from column information. --- lib/simple_form/components/base.rb | 4 ++-- lib/simple_form/components/input.rb | 15 ++++++++++++--- lib/simple_form/form_builder.rb | 12 +++++++----- test/components/input_test.rb | 22 ++++++++++++++++++++++ test/support/models.rb | 15 ++++++++------- test/test_helper.rb | 2 +- 6 files changed, 52 insertions(+), 18 deletions(-) diff --git a/lib/simple_form/components/base.rb b/lib/simple_form/components/base.rb index 475cc29c..c03bc61f 100644 --- a/lib/simple_form/components/base.rb +++ b/lib/simple_form/components/base.rb @@ -8,7 +8,7 @@ module SimpleForm # The Base component is a raw component with some helpers and a default behavior # of prepending the content available in the method content. class Base - delegate :template, :object, :object_name, :column, :attribute, + delegate :template, :object, :object_name, :attribute, :column, :input_type, :options, :to => :@builder def self.basename @@ -47,4 +47,4 @@ module SimpleForm end end end -end \ No newline at end of file +end diff --git a/lib/simple_form/components/input.rb b/lib/simple_form/components/input.rb index f97fa799..636fdeb5 100644 --- a/lib/simple_form/components/input.rb +++ b/lib/simple_form/components/input.rb @@ -27,8 +27,6 @@ module SimpleForm end def content - html_options = options[:html] || {} - html_options[:class] = default_css_classes(html_options[:class]) options[:options] ||= {} mapping = self.class.mappings[input_type] @@ -37,7 +35,7 @@ module SimpleForm args = [ attribute ] apply_collection_behavior(args) if mapping.collection apply_options_behavior(args) if mapping.options - args << html_options + apply_html_options(args) @builder.send(mapping.method, *args) end @@ -56,6 +54,17 @@ module SimpleForm args << options[:options] end + def apply_html_options(args) + html_options = options[:html] || {} + html_options[:class] = default_css_classes(html_options[:class]) + + if column && [:string, :password, :decimal, :float].include?(input_type) + html_options[:maxlength] ||= column.limit + end + + args << html_options + end + def detect_collection_methods(collection, options) sample = collection.first || collection.last diff --git a/lib/simple_form/form_builder.rb b/lib/simple_form/form_builder.rb index f3acc58d..ad52b2de 100644 --- a/lib/simple_form/form_builder.rb +++ b/lib/simple_form/form_builder.rb @@ -1,9 +1,11 @@ module SimpleForm class FormBuilder < ActionView::Helpers::FormBuilder - attr_reader :template, :object_name, :object, :attribute, :input_type, :options + attr_reader :template, :object_name, :object, :attribute, :column, + :input_type, :options def input(attribute, options={}) @attribute, @options = attribute, options + @column = find_attribute_column @input_type = default_input_type component = SimpleForm.terminator @@ -17,10 +19,6 @@ module SimpleForm private - def column - @object.column_for_attribute(@attribute) if @object.respond_to?(:column_for_attribute) - end - def default_input_type return @options[:as].to_sym if @options[:as] return :select if @options[:collection] @@ -37,5 +35,9 @@ module SimpleForm end end + def find_attribute_column + @object.column_for_attribute(@attribute) if @object.respond_to?(:column_for_attribute) + end + end end diff --git a/test/components/input_test.rb b/test/components/input_test.rb index 0c8638c2..0eaa1ace 100644 --- a/test/components/input_test.rb +++ b/test/components/input_test.rb @@ -9,6 +9,7 @@ class InputTest < ActionView::TestCase def with_input_for(object, attribute, type, options={}) simple_form_for object do |f| f.attribute = attribute + f.column = object.column_for_attribute(attribute) if object.respond_to?(:column_for_attribute) f.input_type = type f.options = options @@ -245,6 +246,27 @@ class InputTest < ActionView::TestCase assert_select 'input.optional#user_name' end + test 'input should get options from column definition for string attributes' do + with_input_for @user, :name, :string + assert_select 'input.string[maxlength=100]' + end + + test 'input should get options from column definition for decimal attributes' do + with_input_for @user, :credit_limit, :decimal + assert_select 'input.decimal[maxlength=15]' + end + + test 'input should get options from column definition for password attributes' do + with_input_for @user, :password, :password + assert_select 'input.password[maxlength=100]' + end + + test 'input should not generate options for different attributes' do + with_input_for @user, :description, :text + assert_select 'textarea' + assert_no_select 'textarea[maxlength]' + end + test 'input should be generated properly when object is not present' do with_input_for :project, :name, :string assert_select 'input.string.required#project_name' diff --git a/test/support/models.rb b/test/support/models.rb index e2eaba24..bc6f454f 100644 --- a/test/support/models.rb +++ b/test/support/models.rb @@ -1,11 +1,12 @@ require 'ostruct' class Column - attr_accessor :name, :type#, :limit, :precision, :scale + attr_accessor :name, :type, :limit#, :precision, :scale def initialize(attrs={}) - self.name = attrs[:name] - self.type = attrs[:type] + self.name = attrs[:name] + self.type = attrs[:type] + self.limit = attrs[:limit] end end @@ -22,18 +23,18 @@ class User < OpenStruct end def column_for_attribute(attribute) - column_type = case attribute.to_sym - when :name, :status, :password then :string + column_type, limit = case attribute.to_sym + when :name, :status, :password then [:string, 100] when :description then :text when :age then :integer - when :credit_limit then :decimal + when :credit_limit then [:decimal, 15] when :active then :boolean when :born_at then :date when :delivery_time then :time when :created_at then :datetime when :updated_at then :timestamp end - Column.new(:name => attribute, :type => column_type) + Column.new(:name => attribute, :type => column_type, :limit => limit) end def human_attribute_name(attribute) diff --git a/test/test_helper.rb b/test/test_helper.rb index 050b7fc2..ecbf8273 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -16,7 +16,7 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f } I18n.default_locale = :en class SimpleForm::FormBuilder - attr_accessor :attribute, :input_type, :options + attr_accessor :attribute, :column, :input_type, :options end class ActionView::TestCase