class ActiveModel::Hints

Active Model Hints

p = Person.new p.hints p.hints

more documentation needed

Constants

CALLBACKS_OPTIONS
MESSAGES_FOR_OPTIONS

and these? validates_with validates_each

MESSAGES_FOR_VALIDATORS
OPTIONS_THAT_WE_DONT_USE_YET
VALIDATORS_THAT_WE_DONT_KNOW_WHAT_TO_DO_WITH
VALIDATORS_WITHOUT_MAIN_KEYS

Attributes

messages[R]

Should virtual element for

validates :email, :confirmation => true
validates :email_confirmation, :presence => true

also have a hint?

Public Class Methods

new(base) click to toggle source

Pass in the instance of the object that is using the errors object.

class Person
  def initialize
    @errors = ActiveModel::Errors.new(self)
  end
end
# File lib/active_model/hints.rb, line 38
def initialize(base)
  @base     = base
  @messages = ActiveSupport::OrderedHash.new
  @base.attributes.keys.each do |a|
    @messages[a.to_sym] = hints_for(a.to_sym)
  end
end

Public Instance Methods

[](attribute) click to toggle source

When passed a symbol or a name of a method, returns an array of hints for the method.

p.hints[:name]   # => ["can not be nil"]
p.hints['name']  # => ["can not be nil"]
# File lib/active_model/hints.rb, line 117
def [](attribute)
  get(attribute.to_sym) || set(attribute.to_sym, [])
end
[]=(attribute, hint) click to toggle source

Adds to the supplied attribute the supplied hint message.

p.hints[:name] = "must be set"
p.hints[:name] # => ['must be set']
# File lib/active_model/hints.rb, line 125
def []=(attribute, hint)
  self[attribute] << hint
end
add(attribute, message = nil, options = {}) click to toggle source

Adds message to the hint messages on attribute. More than one hint can be added to the same attribute. If no message is supplied, :invalid is assumed.

If message is a symbol, it will be translated using the appropriate scope (see translate_hint). If message is a proc, it will be called, allowing for things like Time.now to be used within an hint.

# File lib/active_model/hints.rb, line 224
def add(attribute, message = nil, options = {})
  message = normalize_message(attribute, message, options)
  if options[:strict]
    raise ActiveModel::StrictValidationFailed, full_message(attribute, message)
  end

  self[attribute] << message
end
add_on_blank(attributes, options = {}) click to toggle source

Will add an hint message to each of the attributes in attributes that is blank (using Object#blank?).

# File lib/active_model/hints.rb, line 243
def add_on_blank(attributes, options = {})
  [attributes].flatten.each do |attribute|
    value = @base.send(:read_attribute_for_validation, attribute)
    add(attribute, :blank, options) if value.blank?
  end
end
add_on_empty(attributes, options = {}) click to toggle source

Will add an hint message to each of the attributes in attributes that is empty.

# File lib/active_model/hints.rb, line 234
def add_on_empty(attributes, options = {})
  [attributes].flatten.each do |attribute|
    value = @base.send(:read_attribute_for_validation, attribute)
    is_empty = value.respond_to?(:empty?) ? value.empty? : false
    add(attribute, :empty, options) if value.nil? || is_empty
  end
end
added?(attribute, message = nil, options = {}) click to toggle source

Returns true if an hint on the attribute with the given message is present, false otherwise. message is treated the same as for add.

p.hints.add :name, :blank
p.hints.added? :name, :blank # => true
# File lib/active_model/hints.rb, line 254
def added?(attribute, message = nil, options = {})
  message = normalize_message(attribute, message, options)
  self[attribute].include? message
end
as_json(options=nil) click to toggle source

Returns an ActiveSupport::OrderedHash that can be used as the JSON representation for this object.

# File lib/active_model/hints.rb, line 210
def as_json(options=nil)
  to_hash
end
blank?()
Alias for: empty?
clear() click to toggle source

Clear the messages

# File lib/active_model/hints.rb, line 87
def clear
  messages.clear
end
count() click to toggle source

Returns the number of hint messages.

p.hints.add(:name, "can't be blank")
p.hints.count # => 1
p.hints.add(:name, "must be specified")
p.hints.count # => 2
# File lib/active_model/hints.rb, line 183
def count
  to_a.size
end
delete(key) click to toggle source

Delete messages for key

# File lib/active_model/hints.rb, line 108
def delete(key)
  messages.delete(key)
end
each() { |attribute, hint| ... } click to toggle source

Iterates through each hint key, value pair in the hint messages hash. Yields the attribute and the hint for that attribute. If the attribute has more than one hint message, yields once for each hint message.

p.hints.add(:name, "can't be blank")
p.hints.each do |attribute, hints_array|
  # Will yield :name and "can't be blank"
end

p.hints.add(:name, "must be specified")
p.hints.each do |attribute, hints_array|
  # Will yield :name and "can't be blank"
  # then yield :name and "must be specified"
end
# File lib/active_model/hints.rb, line 143
def each
  messages.each_key do |attribute|
    self[attribute].each { |hint| yield attribute, hint }
  end
end
empty?() click to toggle source

Returns true if no hints are found, false otherwise. If the hint message is a string it can be empty.

# File lib/active_model/hints.rb, line 189
def empty?
  all? { |k, v| v && v.empty? && !v.is_a?(String) }
end
Also aliased as: blank?
full_message(attribute, message) click to toggle source

Returns a full message for a given attribute.

company.hints.full_message(:name, "is invalid")  # =>
  "Name is invalid"
# File lib/active_model/hints.rb, line 277
def full_message(attribute, message)
  return message if attribute == :base
  attr_name = attribute.to_s.gsub('.', '_').humanize
  attr_name = @base.class.human_attribute_name(attribute, :default => attr_name)
  I18n.t(:"hints.format", 
      :default   => "%{attribute} %{message}",
      :attribute => attr_name,
      :message   => message
      )
end
full_messages() click to toggle source

Returns all the full hint messages in an array.

class Company
  validates_presence_of :name, :address, :email
  validates_length_of :name, :in => 5..30
end

company = Company.create(:address => '123 First St.')
company.hints.full_messages # =>
  ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Email can't be blank"]
# File lib/active_model/hints.rb, line 269
def full_messages
  map { |attribute, message| full_message(attribute, message) }
end
full_messages_for(attribute) click to toggle source
# File lib/active_model/hints.rb, line 69
def full_messages_for(attribute)
  hints_for(attribute).map { |message| full_message(attribute, message) }
end
generate_message(attribute, type, options = {}) click to toggle source
# File lib/active_model/hints.rb, line 288
def generate_message(attribute, type, options = {})
  #options.delete(:message) if options[:message].is_a?(Symbol)
  if @base.class.respond_to?(:i18n_scope)
    defaults = @base.class.lookup_ancestors.map do |klass|
      [ :"#{@base.class.i18n_scope}.hints.models.#{klass.model_name.i18n_key}.attributes.#{attribute}.#{type}",
        :"#{@base.class.i18n_scope}.hints.models.#{klass.model_name.i18n_key}.#{type}" ]
    end
  else
    defaults = []
  end

  defaults << options[:message] # defaults << options.delete(:message)
  defaults << :"#{@base.class.i18n_scope}.hints.messages.#{type}" if @base.class.respond_to?(:i18n_scope)
  defaults << :"hints.attributes.#{attribute}.#{type}"
  defaults << :"hints.messages.#{type}"

  defaults.compact!
  defaults.flatten!

  key = defaults.shift

  # options = {
  #   :default => defaults,
  #   :model => @base.class.model_name.human,
  #   :attribute => @base.class.human_attribute_name(attribute),
  # }.merge(options)
  I18n.translate( key,  
                  default:   defaults,
                  model:     @base.class.model_name.human,
                  attribute: @base.class.human_attribute_name(attribute),
                  count:     options[:count],
                  )
end
get(key) click to toggle source

Get messages for key

# File lib/active_model/hints.rb, line 98
def get(key)
  messages[key]
end
has_key?(hint)
Alias for: include?
hints_for(attribute) click to toggle source
# File lib/active_model/hints.rb, line 46
def hints_for(attribute)
  result = Array.new
  @base.class.validators_on(attribute).map do |v|
    validator = v.class.to_s.split('::').last.underscore.gsub('_validator','')
    if v.options[:message].is_a?(Symbol)
      message_key =  [validator, v.options[:message]].join('.') # if a message was supplied as a symbol, we use it instead
      result << generate_message(attribute, message_key, v.options)
    else
      message_key =  validator
      message_key =  [validator, ".must_be_a_number"].join('.') if validator == 'numericality' # create an option for numericality; the way YAML works a key (numericality) with subkeys (greater_than, etc etc) can not have a string itself. So we create a subkey for numericality
      result << generate_message(attribute, message_key, v.options) unless VALIDATORS_WITHOUT_MAIN_KEYS.include?(validator)
      v.options.each do |o|
        if MESSAGES_FOR_OPTIONS.include?(o.first.to_s)
          count = o.last
          count = (o.last.to_sentence if %w(inclusion exclusion).include?(validator)) rescue o.last
          result << generate_message(attribute, [ validator, o.first.to_s ].join('.'), { :count => count } )
        end
      end
    end
  end
  result
end
include?(hint) click to toggle source

Do the hint messages include an hint with key hint?

# File lib/active_model/hints.rb, line 92
def include?(hint)
  (v = messages[hint]) && v.any?
end
Also aliased as: has_key?
initialize_dup(other) click to toggle source
# File lib/active_model/hints.rb, line 73
def initialize_dup(other)
  @messages = other.messages.dup
end
keys() click to toggle source

Returns all message keys

# File lib/active_model/hints.rb, line 165
def keys
  messages.keys
end
set(key, value) click to toggle source

Set messages for key to value

# File lib/active_model/hints.rb, line 103
def set(key, value)
  messages[key] = value
end
size() click to toggle source

Returns the number of error messages.

p.hints.add(:name, "can't be blank")
p.hints.size # => 1
p.hints.add(:name, "must be specified")
p.hints.size # => 2
# File lib/active_model/hints.rb, line 155
def size
  values.flatten.size
end
to_a() click to toggle source

Returns an array of hint messages, with the attribute name included

p.hints.add(:name, "can't be blank")
p.hints.add(:name, "must be specified")
p.hints.to_a # => ["name can't be blank", "name must be specified"]
# File lib/active_model/hints.rb, line 174
def to_a
  full_messages
end
to_hash() click to toggle source
# File lib/active_model/hints.rb, line 214
def to_hash
  messages.dup
end
to_xml(options={}) click to toggle source

Returns an xml formatted representation of the hints hash.

p.hints.add(:name, "can't be blank")
p.hints.add(:name, "must be specified")
p.hints.to_xml
# =>
#  <?xml version=\"1.0\" encoding=\"UTF-8\"?>
#  <hints>
#    <hint>name can't be blank</hint>
#    <hint>name must be specified</hint>
#  </hints>
# File lib/active_model/hints.rb, line 205
def to_xml(options={})
  to_a.to_xml options.reverse_merge(:root => "hints", :skip_types => true)
end
values() click to toggle source

Returns all message values

# File lib/active_model/hints.rb, line 160
def values
  messages.values
end