Skip to content

Commit

Permalink
error_message_on takes an options hash instead of ordered parameters [#…
Browse files Browse the repository at this point in the history
…704 state:resolved]

Signed-off-by: Joshua Peek <josh@joshpeek.com>
  • Loading branch information
clemens authored and josh committed Jul 27, 2008
1 parent 490178c commit f7abf0c
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 40 deletions.
46 changes: 32 additions & 14 deletions actionpack/lib/action_view/helpers/active_record_helper.rb
Expand Up @@ -25,7 +25,7 @@ def input(record_name, method, options = {})
# Returns an entire form with all needed input tags for a specified Active Record object. For example, if <tt>@post</tt>
# has attributes named +title+ of type +VARCHAR+ and +body+ of type +TEXT+ then
#
# form("post")
# form("post")
#
# would yield a form like the following (modulus formatting):
#
Expand Down Expand Up @@ -90,23 +90,41 @@ def form(record_name, options = {})
end

# Returns a string containing the error message attached to the +method+ on the +object+ if one exists.
# This error message is wrapped in a <tt>DIV</tt> tag, which can be extended to include a +prepend_text+ and/or +append_text+
# (to properly explain the error), and a +css_class+ to style it accordingly. +object+ should either be the name of an instance variable or
# the actual object. As an example, let's say you have a model <tt>@post</tt> that has an error message on the +title+ attribute:
# This error message is wrapped in a <tt>DIV</tt> tag, which can be extended to include a <tt>:prepend_text</tt>
# and/or <tt>:append_text</tt> (to properly explain the error), and a <tt>:css_class</tt> to style it
# accordingly. +object+ should either be the name of an instance variable or the actual object. The method can be
# passed in either as a string or a symbol.
# As an example, let's say you have a model <tt>@post</tt> that has an error message on the +title+ attribute:
#
# <%= error_message_on "post", "title" %>
# # => <div class="formError">can't be empty</div>
#
# <%= error_message_on @post, "title" %>
# <%= error_message_on @post, :title %>
# # => <div class="formError">can't be empty</div>
#
# <%= error_message_on "post", "title", "Title simply ", " (or it won't work).", "inputError" %>
# # => <div class="inputError">Title simply can't be empty (or it won't work).</div>
def error_message_on(object, method, prepend_text = "", append_text = "", css_class = "formError")
# <%= error_message_on "post", "title",
# :prepend_text => "Title simply ",
# :append_text => " (or it won't work).",
# :css_class => "inputError" %>
def error_message_on(object, method, *args)
options = args.extract_options!
unless args.empty?
ActiveSupport::Deprecation.warn('error_message_on takes an option hash instead of separate' +
'prepend_text, append_text, and css_class arguments', caller)

options[:prepend_text] = args[0] || ''
options[:append_text] = args[1] || ''
options[:css_class] = args[2] || 'formError'
end
options.reverse_merge!(:prepend_text => '', :append_text => '', :css_class => 'formError')

if (obj = (object.respond_to?(:errors) ? object : instance_variable_get("@#{object}"))) &&
(errors = obj.errors.on(method))
content_tag("div", "#{prepend_text}#{errors.is_a?(Array) ? errors.first : errors}#{append_text}", :class => css_class)
else
content_tag("div",
"#{options[:prepend_text]}#{errors.is_a?(Array) ? errors.first : errors}#{options[:append_text]}",
:class => options[:css_class]
)
else
''
end
end
Expand All @@ -133,7 +151,7 @@ def error_message_on(object, method, prepend_text = "", append_text = "", css_cl
#
# To specify the display for one object, you simply provide its name as a parameter.
# For example, for the <tt>@user</tt> model:
#
#
# error_messages_for 'user'
#
# To specify more than one object, you simply list them; optionally, you can add an extra <tt>:object_name</tt> parameter, which
Expand All @@ -157,7 +175,7 @@ def error_messages_for(*params)
else
objects = params.collect {|object_name| instance_variable_get("@#{object_name}") }.compact
end

count = objects.inject(0) {|sum, object| sum + object.errors.count }
unless count.zero?
html = {}
Expand All @@ -174,7 +192,7 @@ def error_messages_for(*params)
I18n.with_options :locale => options[:locale], :scope => [:active_record, :error] do |locale|
header_message = if options.include?(:header_message)
options[:header_message]
else
else
object_name = options[:object_name].to_s.gsub('_', ' ')
object_name = I18n.t(object_name, :default => object_name)
locale.t :header_message, :count => count, :object_name => object_name
Expand All @@ -193,7 +211,7 @@ def error_messages_for(*params)
''
end
end

private
def all_input_tags(record, record_name, options)
input_block = options[:input_block] || default_input_block
Expand Down
4 changes: 2 additions & 2 deletions actionpack/lib/action_view/helpers/form_helper.rb
Expand Up @@ -782,8 +782,8 @@ def radio_button(method, tag_value, options = {})
@template.radio_button(@object_name, method, tag_value, objectify_options(options))
end

def error_message_on(method, prepend_text = "", append_text = "", css_class = "formError")
@template.error_message_on(@object, method, prepend_text, append_text, css_class)
def error_message_on(method, *args)
@template.error_message_on(@object, method, *args)
end

def error_messages(options = {})
Expand Down
48 changes: 24 additions & 24 deletions actionpack/test/template/active_record_helper_test.rb
Expand Up @@ -10,17 +10,17 @@ class ActiveRecordHelperTest < ActionView::TestCase
alias_method :body_before_type_cast, :body unless respond_to?(:body_before_type_cast)
alias_method :author_name_before_type_cast, :author_name unless respond_to?(:author_name_before_type_cast)
end

User = Struct.new("User", :email)
User.class_eval do
alias_method :email_before_type_cast, :email unless respond_to?(:email_before_type_cast)
end

Column = Struct.new("Column", :type, :name, :human_name)
end

def setup_post
@post = Post.new
@post = Post.new
def @post.errors
Class.new {
def on(field)
Expand All @@ -33,12 +33,12 @@ def on(field)
false
end
end
def empty?() false end
def count() 1 end
def empty?() false end
def count() 1 end
def full_messages() [ "Author name can't be empty" ] end
}.new
end

def @post.new_record?() true end
def @post.to_param() nil end

Expand All @@ -58,16 +58,16 @@ def Post.content_columns() [ Column.new(:string, "title", "Title"), Column.new(:
end

def setup_user
@user = User.new
@user = User.new
def @user.errors
Class.new {
def on(field) field == "email" end
def empty?() false end
def count() 1 end
def empty?() false end
def count() 1 end
def full_messages() [ "User email can't be empty" ] end
}.new
end

def @user.new_record?() true end
def @user.to_param() nil end

Expand All @@ -81,7 +81,7 @@ def User.content_columns() [ Column.new(:string, "email", "Email") ] end

@user.email = ""
end

def protect_against_forgery?
@protect_against_forgery ? true : false
end
Expand All @@ -92,7 +92,7 @@ def setup
setup_user

@response = ActionController::TestResponse.new

@controller = Object.new
def @controller.url_for(options)
options = options.symbolize_keys
Expand All @@ -111,7 +111,7 @@ def test_text_area_with_errors
assert_dom_equal(
%(<div class="fieldWithErrors"><textarea cols="40" id="post_body" name="post[body]" rows="20">Back to the hill and over it again!</textarea></div>),
text_area("post", "body")
)
)
end

def test_text_field_with_errors
Expand Down Expand Up @@ -140,7 +140,7 @@ def id() 1 end
form("post")
)
end

def test_form_with_protect_against_forgery
@protect_against_forgery = true
@request_forgery_protection_token = 'authenticity_token'
Expand All @@ -150,7 +150,7 @@ def test_form_with_protect_against_forgery
form("post")
)
end

def test_form_with_method_option
assert_dom_equal(
%(<form action="create" method="get"><p><label for="post_title">Title</label><br /><input id="post_title" name="post[title]" size="30" type="text" value="Hello World" /></p>\n<p><label for="post_body">Body</label><br /><div class="fieldWithErrors"><textarea cols="40" id="post_body" name="post[body]" rows="20">Back to the hill and over it again!</textarea></div></p><input name="commit" type="submit" value="Create" /></form>),
Expand Down Expand Up @@ -211,9 +211,9 @@ def test_error_message_on_no_instance_variable
other_post = @post
assert_dom_equal "<div class=\"formError\">can't be empty</div>", error_message_on(other_post, :author_name)
end
def test_error_message_on_should_use_options
assert_dom_equal "<div class=\"differentError\">beforecan't be emptyafter</div>", error_message_on(:post, :author_name, "before", "after", "differentError")

def test_error_message_on_with_options_hash
assert_dom_equal "<div class=\"differentError\">beforecan't be emptyafter</div>", error_message_on(:post, :author_name, :css_class => 'differentError', :prepend_text => 'before', :append_text => 'after')
end

def test_error_messages_for_many_objects
Expand All @@ -224,10 +224,10 @@ def test_error_messages_for_many_objects

# add the default to put post back in the title
assert_dom_equal %(<div class="errorExplanation" id="errorExplanation"><h2>2 errors prohibited this post from being saved</h2><p>There were problems with the following fields:</p><ul><li>User email can't be empty</li><li>Author name can't be empty</li></ul></div>), error_messages_for("user", "post", :object_name => "post")

# symbols work as well
assert_dom_equal %(<div class="errorExplanation" id="errorExplanation"><h2>2 errors prohibited this post from being saved</h2><p>There were problems with the following fields:</p><ul><li>User email can't be empty</li><li>Author name can't be empty</li></ul></div>), error_messages_for(:user, :post, :object_name => :post)

# any default works too
assert_dom_equal %(<div class="errorExplanation" id="errorExplanation"><h2>2 errors prohibited this monkey from being saved</h2><p>There were problems with the following fields:</p><ul><li>User email can't be empty</li><li>Author name can't be empty</li></ul></div>), error_messages_for(:user, :post, :object_name => "monkey")

Expand All @@ -242,7 +242,7 @@ def test_error_messages_for_many_objects
message = "Please fix the following fields and resubmit:"
assert_dom_equal %(<div class="errorExplanation" id="errorExplanation"><h2>#{header_message}</h2><p>#{message}</p><ul><li>User email can't be empty</li><li>Author name can't be empty</li></ul></div>), error_messages_for(:user, :post, :header_message => header_message, :message => message)
end

def test_error_messages_for_non_instance_variable
actual_user = @user
actual_post = @post
Expand All @@ -251,14 +251,14 @@ def test_error_messages_for_non_instance_variable

#explicitly set object
assert_dom_equal %(<div class="errorExplanation" id="errorExplanation"><h2>1 error prohibited this post from being saved</h2><p>There were problems with the following fields:</p><ul><li>Author name can't be empty</li></ul></div>), error_messages_for("post", :object => actual_post)

#multiple objects
assert_dom_equal %(<div class="errorExplanation" id="errorExplanation"><h2>2 errors prohibited this user from being saved</h2><p>There were problems with the following fields:</p><ul><li>User email can't be empty</li><li>Author name can't be empty</li></ul></div>), error_messages_for("user", "post", :object => [actual_user, actual_post])

#nil object
assert_equal '', error_messages_for('user', :object => nil)
end

def test_form_with_string_multipart
assert_dom_equal(
%(<form action="create" enctype="multipart/form-data" method="post"><p><label for="post_title">Title</label><br /><input id="post_title" name="post[title]" size="30" type="text" value="Hello World" /></p>\n<p><label for="post_body">Body</label><br /><div class="fieldWithErrors"><textarea cols="40" id="post_body" name="post[body]" rows="20">Back to the hill and over it again!</textarea></div></p><input name="commit" type="submit" value="Create" /></form>),
Expand Down

0 comments on commit f7abf0c

Please sign in to comment.