mirror of
https://github.com/heartcombo/simple_form.git
synced 2022-11-09 12:19:26 -05:00
Lookup errors in associations.
This commit is contained in:
parent
94cb1efe00
commit
461f309bc7
6 changed files with 32 additions and 15 deletions
|
@ -9,7 +9,7 @@ module SimpleForm
|
|||
# of prepending the content available in the method content.
|
||||
class Base
|
||||
delegate :template, :object, :object_name, :attribute, :column,
|
||||
:input_type, :options, :to => :@builder
|
||||
:reflection, :input_type, :options, :to => :@builder
|
||||
|
||||
def self.basename
|
||||
@basename ||= name.split("::").last.underscore.to_sym
|
||||
|
|
|
@ -9,11 +9,19 @@ module SimpleForm
|
|||
end
|
||||
|
||||
def errors
|
||||
@errors ||= object.errors[attribute]
|
||||
@errors ||= (errors_on_attribute + errors_on_association).compact
|
||||
end
|
||||
|
||||
def errors_on_attribute
|
||||
Array(object.errors[attribute])
|
||||
end
|
||||
|
||||
def errors_on_association
|
||||
reflection ? Array(object.errors[reflection.name]) : []
|
||||
end
|
||||
|
||||
def content
|
||||
component_tag Array(errors).to_sentence
|
||||
component_tag errors.to_sentence
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
module SimpleForm
|
||||
class FormBuilder < ActionView::Helpers::FormBuilder
|
||||
attr_reader :template, :object_name, :object, :attribute, :column, :input_type, :options
|
||||
attr_reader :template, :object_name, :object, :attribute, :column,
|
||||
:reflection, :input_type, :options
|
||||
|
||||
TERMINATOR = lambda { "" }
|
||||
|
||||
# Basic input helper, combines all components in the stack to generate input
|
||||
# html based on options the user define and some guesses through
|
||||
# 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
|
||||
# label + input + hint (when defined) + errors (when exists), and all can be
|
||||
# configured inside a wrapper html.
|
||||
# label + input + hint (when defined) + errors (when exists), and all can
|
||||
# be configured inside a wrapper html.
|
||||
#
|
||||
# == Examples:
|
||||
#
|
||||
|
@ -98,18 +99,18 @@ module SimpleForm
|
|||
def association(attribute, options={})
|
||||
raise ArgumentError, "Association cannot be used in forms not associated with an object" unless @object
|
||||
|
||||
association = find_association(attribute)
|
||||
raise "Association not found #{attribute.inspect}" unless association
|
||||
@reflection = find_association_reflection(attribute)
|
||||
raise "Association not found #{attribute.inspect}" unless @reflection
|
||||
|
||||
attribute = association.options[:foreign_key] || :"#{association.name}_id"
|
||||
attribute = @reflection.options[:foreign_key] || :"#{@reflection.name}_id"
|
||||
|
||||
options[:collection] ||= begin
|
||||
find_options = { :conditions => options.delete(:conditions),
|
||||
:order => options.delete(:order) }
|
||||
association.klass.all(find_options)
|
||||
@reflection.klass.all(find_options)
|
||||
end
|
||||
|
||||
input(attribute, options)
|
||||
returning(input(attribute, options)) { @reflection = nil }
|
||||
end
|
||||
|
||||
# Creates a button:
|
||||
|
@ -248,7 +249,7 @@ module SimpleForm
|
|||
end
|
||||
|
||||
# Find association related to attribute
|
||||
def find_association(attribute)
|
||||
def find_association_reflection(attribute)
|
||||
@object.class.reflect_on_association(attribute) if @object.class.respond_to?(:reflect_on_association)
|
||||
end
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ class ErrorTest < ActionView::TestCase
|
|||
def with_error_for(object, attribute, type, options={}, &block)
|
||||
simple_form_for object do |f|
|
||||
f.attribute = attribute
|
||||
f.reflection = Association.new(Company, :company, {}) if options.delete(:setup_association)
|
||||
f.input_type = type
|
||||
f.options = options
|
||||
|
||||
|
@ -46,4 +47,9 @@ class ErrorTest < ActionView::TestCase
|
|||
with_error_for @user, :name, :string, :error_html => { :id => 'error', :class => 'yay' }
|
||||
assert_select 'span#error.error.yay'
|
||||
end
|
||||
|
||||
test 'error should find errors on attribute and association' do
|
||||
with_error_for @user, :company_id, :select, :setup_association => true
|
||||
assert_select 'span.error', 'must be valid and company must be present'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -64,6 +64,8 @@ class User < OpenStruct
|
|||
:name => "can't be blank",
|
||||
:description => "must be longer than 15 characters",
|
||||
:age => ["is not a number", "must be greater than 18"],
|
||||
:company => "company must be present",
|
||||
:company_id => "must be valid"
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,7 +16,7 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
|||
I18n.default_locale = :en
|
||||
|
||||
class SimpleForm::FormBuilder
|
||||
attr_accessor :attribute, :column, :input_type, :options
|
||||
attr_accessor :attribute, :column, :reflection, :input_type, :options
|
||||
end
|
||||
|
||||
class ActionView::TestCase
|
||||
|
|
Loading…
Reference in a new issue