Add inputs discovery.

This commit is contained in:
José Valim 2011-04-27 20:55:03 +02:00
parent 70c2c563d0
commit 1520353fc2
5 changed files with 69 additions and 6 deletions

View File

@ -1,6 +1,6 @@
source "http://rubygems.org"
gem "rails", "~> 3.0.0"
gem "rails", "~> 3.0.7"
group :test do
gem "mocha", :require => false

View File

@ -35,7 +35,7 @@ GEM
abstract (>= 1.0.0)
i18n (0.5.0)
linecache (0.43)
mail (2.2.17)
mail (2.2.18)
activesupport (>= 2.3.6)
i18n (>= 0.4.0)
mime-types (~> 1.16)
@ -71,12 +71,12 @@ GEM
thor (0.14.6)
treetop (1.4.9)
polyglot (>= 0.3.1)
tzinfo (0.3.26)
tzinfo (0.3.27)
PLATFORMS
ruby
DEPENDENCIES
mocha
rails (~> 3.0.0)
rails (~> 3.0.7)
ruby-debug

View File

@ -128,6 +128,14 @@ module SimpleForm
mattr_accessor :translate
@@translate = true
# Automatically discover new inputs in Rails' autoload path.
mattr_accessor :inputs_discovery
@@inputs_discovery = true
# Cache simple form inputs discovery
mattr_accessor :cache_discovery
@@cache_discovery = !Rails.env.development?
# Default way to setup SimpleForm. Run rails generate simple_form:install
# to create a fresh initializer with all configuration values.
def self.setup

View File

@ -13,6 +13,10 @@ module SimpleForm
map_type :country, :time_zone, :to => SimpleForm::Inputs::PriorityInput
map_type :boolean, :to => SimpleForm::Inputs::BooleanInput
def self.discovery_cache
@discovery_cache ||= {}
end
# Basic input helper, combines all components in the stack to generate
# input html based on options the user define and some guesses through
# database column information. By default a call to input will generate
@ -85,8 +89,7 @@ module SimpleForm
if block_given?
SimpleForm::Inputs::BlockInput.new(self, attribute_name, column, input_type, options, &block).render
else
klass = self.class.mappings[input_type] || self.class.const_get("#{input_type.to_s.camelize}Input")
klass.new(self, attribute_name, column, input_type, options).render
find_mapping(input_type).new(self, attribute_name, column, input_type, options).render
end
end
alias :attribute :input
@ -314,5 +317,51 @@ module SimpleForm
@object.class.reflect_on_association(association)
end
end
# Attempts to find a mapping. It follows the following rules:
#
# 1) It tries to find a registered mapping, if succeeds:
# a) If a mapping is found, try to find an alternative as #{mapping}Input
# b) Or use the found mapping
# 2) If not, fallbacks to #{input_type}Input
# 3) If not, fallbacks to SimpleForm::Inputs::#{input_type}
def find_mapping(input_type) #:nodoc:
discovery_cache[input_type] ||=
if mapping = self.class.mappings[input_type]
mapping_override(mapping) || mapping
else
camelized = "#{input_type.to_s.camelize}Input"
attempt_mapping(camelized, Object) || attempt_mapping(camelized, self.class) ||
raise("No input found for #{input_type}")
end
end
# If cache_discovery is enabled, use the class level cache that persists
# between requests, otherwise use the instance one.
def discovery_cache #:nodoc:
if SimpleForm.cache_discovery
self.class.discovery_cache
else
@discovery_cache ||= {}
end
end
def mapping_override(klass) #:nodoc:
name = klass.name
if name =~ /^SimpleForm::Inputs/
attempt = "#{name.split("::").last}Input"
attempt_mapping attempt, Object
end
end
def attempt_mapping(mapping, at) #:nodoc:
return if SimpleForm.inputs_discovery == false && at == Object
begin
at.const_get(mapping)
rescue NameError => e
e.message =~ /#{mapping}$/ ? nil : raise
end
end
end
end

View File

@ -13,6 +13,12 @@ require 'action_view/template'
require 'active_support/core_ext/module/deprecation'
require 'action_view/test_case'
module Rails
def self.env
ActiveSupport::StringInquirer.new("test")
end
end
$:.unshift File.expand_path("../../lib", __FILE__)
require 'simple_form'