mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Allow error_messages_for to report errors for multiple objects, as well as support for customizing the name of the object in the error summary header. Closes #4186. [andrew@redlinesoftware.com, Marcel Molina Jr.]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4287 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
8ee378f3c4
commit
43ee8ab6e2
3 changed files with 85 additions and 17 deletions
|
@ -1,5 +1,9 @@
|
|||
*SVN*
|
||||
|
||||
* Allow error_messages_for to report errors for multiple objects, as well as support for customizing the name of the object in the error summary header. Closes #4186. [andrew@redlinesoftware.com, Marcel Molina Jr.]
|
||||
|
||||
error_messages_for :account, :user, :subscription, :object_name => :account
|
||||
|
||||
* Enhance documentation for setting headers in integration tests. Skip auto HTTP prepending when its already there. Closes #4079. [Rick Olson]
|
||||
|
||||
* Documentation for AbstractRequest. Closes #4895. [kevin.clark@gmail.com]
|
||||
|
|
|
@ -90,31 +90,45 @@ module ActionView
|
|||
end
|
||||
end
|
||||
|
||||
# Returns a string with a div containing all the error messages for the object located as an instance variable by the name
|
||||
# of <tt>object_name</tt>. This div can be tailored by the following options:
|
||||
# Returns a string with a div containing all of the error messages for the objects located as instance variables by the names
|
||||
# given. If more than one object is specified, the errors for the objects are displayed in the order that the object names are
|
||||
# provided.
|
||||
#
|
||||
# This div can be tailored by the following options:
|
||||
#
|
||||
# * <tt>header_tag</tt> - Used for the header of the error div (default: h2)
|
||||
# * <tt>id</tt> - The id of the error div (default: errorExplanation)
|
||||
# * <tt>class</tt> - The class of the error div (default: errorExplanation)
|
||||
# * <tt>object_name</tt> - The object name to use in the header, or
|
||||
# any text that you prefer. If <tt>object_name</tt> is not set, the name of
|
||||
# the first object will be used.
|
||||
#
|
||||
# Specifying one object:
|
||||
#
|
||||
# error_messages_for 'user'
|
||||
#
|
||||
# Specifying more than one object (and using the name 'user' in the
|
||||
# header as the <tt>object_name</tt> instead of 'user_common'):
|
||||
#
|
||||
# error_messages_for 'user_common', 'user', :object_name => 'user'
|
||||
#
|
||||
# NOTE: This is a pre-packaged presentation of the errors with embedded strings and a certain HTML structure. If what
|
||||
# you need is significantly different from the default presentation, it makes plenty of sense to access the object.errors
|
||||
# instance yourself and set it up. View the source of this method to see how easy it is.
|
||||
def error_messages_for(object_name, options = {})
|
||||
options = options.symbolize_keys
|
||||
object = instance_variable_get("@#{object_name}")
|
||||
if object && !object.errors.empty?
|
||||
content_tag("div",
|
||||
content_tag(
|
||||
options[:header_tag] || "h2",
|
||||
"#{pluralize(object.errors.count, "error")} prohibited this #{object_name.to_s.gsub("_", " ")} from being saved"
|
||||
) +
|
||||
content_tag("p", "There were problems with the following fields:") +
|
||||
content_tag("ul", object.errors.full_messages.collect { |msg| content_tag("li", msg) }),
|
||||
"id" => options[:id] || "errorExplanation", "class" => options[:class] || "errorExplanation"
|
||||
)
|
||||
def error_messages_for(*params)
|
||||
options = params.last.is_a?(Hash) ? params.pop.symbolize_keys : {}
|
||||
objects = params.collect {|object_name| instance_variable_get("@#{object_name}") }.compact
|
||||
count = objects.inject(0) {|sum, object| sum + object.errors.count }
|
||||
unless count.zero?
|
||||
header_message = "#{pluralize(count, 'error')} prohibited this #{(options[:object_name] || params.first).to_s.gsub('_', ' ')} from being saved"
|
||||
error_messages = objects.map {|object| object.errors.full_messages.map {|msg| content_tag(:li, msg) } }
|
||||
content_tag(:div,
|
||||
content_tag(options[:header_tag] || :h2, header_message) <<
|
||||
content_tag(:p, 'There were problems with the following fields:') <<
|
||||
content_tag(:ul, error_messages),
|
||||
:id => options[:id] || 'errorExplanation', :class => options[:class] || 'errorExplanation')
|
||||
else
|
||||
""
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -22,10 +22,16 @@ class ActiveRecordHelperTest < Test::Unit::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
|
||||
def setup_post
|
||||
@post = Post.new
|
||||
def @post.errors
|
||||
Class.new {
|
||||
|
@ -50,6 +56,34 @@ class ActiveRecordHelperTest < Test::Unit::TestCase
|
|||
@post.body = "Back to the hill and over it again!"
|
||||
@post.secret = 1
|
||||
@post.written_on = Date.new(2004, 6, 15)
|
||||
end
|
||||
|
||||
def setup_user
|
||||
@user = User.new
|
||||
def @user.errors
|
||||
Class.new {
|
||||
def on(field) field == "email" 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
|
||||
|
||||
def @user.column_for_attribute(attr_name)
|
||||
User.content_columns.select { |column| column.name == attr_name }.first
|
||||
end
|
||||
|
||||
def User.content_columns() [ Column.new(:string, "email", "Email") ] end
|
||||
|
||||
@user.email = ""
|
||||
end
|
||||
|
||||
def setup
|
||||
setup_post
|
||||
setup_user
|
||||
|
||||
@controller = Object.new
|
||||
def @controller.url_for(options, *parameters_for_method_reference)
|
||||
|
@ -124,6 +158,22 @@ class ActiveRecordHelperTest < Test::Unit::TestCase
|
|||
assert_equal "", error_messages_for("notthere")
|
||||
end
|
||||
|
||||
def test_error_messages_for_many_objects
|
||||
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>Author name can't be empty</li><li>User email can't be empty</li></ul></div>), error_messages_for("post", "user")
|
||||
|
||||
# reverse the order, error order changes and so does the title
|
||||
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")
|
||||
|
||||
# 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")
|
||||
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>),
|
||||
|
|
Loading…
Reference in a new issue