Thursday, December 4, 2008

Rails 2.2.2 + Validatable 1.6.7 + I18N + Error Messages

- Create /lib/errors.rb
module Validatable
class Errors
def validatable_full_messages(obj)
full_messages = []

errors.each_key do |attribute|
errors[attribute].each do |msg|
next if msg.nil?

if attribute.to_s == "base"
full_messages << msg
else
full_messages << I18n.translate("activerecord.attributes.#{obj.class.name.underscore}.#{attribute}") + " " + msg
end
end
end
full_messages
end
end
end


- Add this function to /app/helpers/application_helper.rb

def validatable_error_messages_for(*params)
options = params.extract_options!.symbolize_keys

if object = options.delete(:object)
objects = [object].flatten
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 = {}
[:id, :class].each do |key|
if options.include?(key)
value = options[key]
html[key] = value unless value.blank?
else
html[key] = 'errorExplanation'
end
end
options[:object_name] ||= params.first

I18n.with_options :locale => options[:locale], :scope => [:activerecord, :errors, :template] do |locale|
header_message = if options.include?(:header_message)
options[:header_message]
else
object_name = options[:object_name].to_s.gsub('_', ' ')
object_name = I18n.t(object_name, :default => object_name, :scope => [:activerecord, :models], :count => 1)
locale.t :header, :count => count, :model => object_name
end
message = options.include?(:message) ? options[:message] : locale.t(:body)
error_messages = objects.sum {|object| object.errors.validatable_full_messages(object).map {|msg| content_tag(:li, msg) } }.join

contents = ''
contents << content_tag(options[:header_tag] || :h2, header_message) unless header_message.blank?
contents << content_tag(:p, message) unless message.blank?
contents << content_tag(:ul, error_messages)

content_tag(:div, contents, html)
end
else
''
end
end



- edit /config/environment.rb, add:

require "errors"


- in views, use:

<%= validatable_error_messages_for "inviter" %>


- for i18n file, follow the structure of ActiveRecord

No comments: