validation_hints 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22,6 +22,9 @@ module ActiveModel
22
22
  def initialize(base)
23
23
  @base = base
24
24
  @messages = ActiveSupport::OrderedHash.new
25
+ @base.attributes.keys.each do |a|
26
+ @messages[a.to_sym] = validation_hints_for(a.to_sym)
27
+ end
25
28
  end
26
29
 
27
30
  def initialize_dup(other)
@@ -42,34 +45,223 @@ module ActiveModel
42
45
  messages.clear
43
46
  end
44
47
 
48
+ # Do the hint messages include an hint with key +hint+?
49
+ def include?(hint)
50
+ (v = messages[hint]) && v.any?
51
+ end
52
+ alias :has_key? :include?
53
+
54
+ # Get messages for +key+
55
+ def get(key)
56
+ messages[key]
57
+ end
58
+
59
+ # Set messages for +key+ to +value+
60
+ def set(key, value)
61
+ messages[key] = value
62
+ end
63
+
64
+ # Delete messages for +key+
65
+ def delete(key)
66
+ messages.delete(key)
67
+ end
68
+
69
+ # When passed a symbol or a name of a method, returns an array of hints
70
+ # for the method.
71
+ #
72
+ # p.hints[:name] # => ["can not be nil"]
73
+ # p.hints['name'] # => ["can not be nil"]
74
+ def [](attribute)
75
+ get(attribute.to_sym) || set(attribute.to_sym, [])
76
+ end
77
+
78
+ # Adds to the supplied attribute the supplied hint message.
79
+ #
80
+ # p.hints[:name] = "must be set"
81
+ # p.hints[:name] # => ['must be set']
82
+ def []=(attribute, hint)
83
+ self[attribute] << hint
84
+ end
85
+
86
+ # Iterates through each hint key, value pair in the hint messages hash.
87
+ # Yields the attribute and the hint for that attribute. If the attribute
88
+ # has more than one hint message, yields once for each hint message.
89
+ #
90
+ # p.hints.add(:name, "can't be blank")
91
+ # p.hints.each do |attribute, hints_array|
92
+ # # Will yield :name and "can't be blank"
93
+ # end
94
+ #
95
+ # p.hints.add(:name, "must be specified")
96
+ # p.hints.each do |attribute, hints_array|
97
+ # # Will yield :name and "can't be blank"
98
+ # # then yield :name and "must be specified"
99
+ # end
100
+ def each
101
+ messages.each_key do |attribute|
102
+ self[attribute].each { |hint| yield attribute, hint }
103
+ end
104
+ end
105
+
106
+ # Returns the number of error messages.
107
+ #
108
+ # p.hints.add(:name, "can't be blank")
109
+ # p.hints.size # => 1
110
+ # p.hints.add(:name, "must be specified")
111
+ # p.hints.size # => 2
112
+ def size
113
+ values.flatten.size
114
+ end
115
+
116
+ # Returns all message values
117
+ def values
118
+ messages.values
119
+ end
120
+
121
+ # Returns all message keys
122
+ def keys
123
+ messages.keys
124
+ end
125
+
126
+ # Returns an array of hint messages, with the attribute name included
127
+ #
128
+ # p.hints.add(:name, "can't be blank")
129
+ # p.hints.add(:name, "must be specified")
130
+ # p.hints.to_a # => ["name can't be blank", "name must be specified"]
131
+ def to_a
132
+ full_messages
133
+ end
134
+
135
+ # Returns the number of hint messages.
136
+ # p.hints.add(:name, "can't be blank")
137
+ # p.hints.count # => 1
138
+ # p.hints.add(:name, "must be specified")
139
+ # p.hints.count # => 2
140
+ def count
141
+ to_a.size
142
+ end
143
+
144
+ # Returns true if no hints are found, false otherwise.
145
+ # If the hint message is a string it can be empty.
146
+ def empty?
147
+ all? { |k, v| v && v.empty? && !v.is_a?(String) }
148
+ end
149
+ alias_method :blank?, :empty?
150
+
151
+ # Returns an xml formatted representation of the hints hash.
152
+ #
153
+ # p.hints.add(:name, "can't be blank")
154
+ # p.hints.add(:name, "must be specified")
155
+ # p.hints.to_xml
156
+ # # =>
157
+ # # <?xml version=\"1.0\" encoding=\"UTF-8\"?>
158
+ # # <hints>
159
+ # # <hint>name can't be blank</hint>
160
+ # # <hint>name must be specified</hint>
161
+ # # </hints>
162
+ def to_xml(options={})
163
+ to_a.to_xml options.reverse_merge(:root => "hints", :skip_types => true)
164
+ end
165
+
166
+ # Returns an ActiveSupport::OrderedHash that can be used as the JSON representation for this object.
167
+ def as_json(options=nil)
168
+ to_hash
169
+ end
170
+
171
+ def to_hash
172
+ messages.dup
173
+ end
174
+
175
+ # Adds +message+ to the hint messages on +attribute+. More than one hint can be added to the same
176
+ # +attribute+.
177
+ # If no +message+ is supplied, <tt>:invalid</tt> is assumed.
178
+ #
179
+ # If +message+ is a symbol, it will be translated using the appropriate scope (see +translate_hint+).
180
+ # If +message+ is a proc, it will be called, allowing for things like <tt>Time.now</tt> to be used within an hint.
181
+ def add(attribute, message = nil, options = {})
182
+ message = normalize_message(attribute, message, options)
183
+ if options[:strict]
184
+ raise ActiveModel::StrictValidationFailed, full_message(attribute, message)
185
+ end
186
+
187
+ self[attribute] << message
188
+ end
189
+
190
+ # Will add an hint message to each of the attributes in +attributes+ that is empty.
191
+ def add_on_empty(attributes, options = {})
192
+ [attributes].flatten.each do |attribute|
193
+ value = @base.send(:read_attribute_for_validation, attribute)
194
+ is_empty = value.respond_to?(:empty?) ? value.empty? : false
195
+ add(attribute, :empty, options) if value.nil? || is_empty
196
+ end
197
+ end
198
+
199
+ # Will add an hint message to each of the attributes in +attributes+ that is blank (using Object#blank?).
200
+ def add_on_blank(attributes, options = {})
201
+ [attributes].flatten.each do |attribute|
202
+ value = @base.send(:read_attribute_for_validation, attribute)
203
+ add(attribute, :blank, options) if value.blank?
204
+ end
205
+ end
206
+
207
+ # Returns true if an hint on the attribute with the given message is present, false otherwise.
208
+ # +message+ is treated the same as for +add+.
209
+ # p.hints.add :name, :blank
210
+ # p.hints.added? :name, :blank # => true
211
+ def added?(attribute, message = nil, options = {})
212
+ message = normalize_message(attribute, message, options)
213
+ self[attribute].include? message
214
+ end
215
+
216
+ # Returns all the full hint messages in an array.
217
+ #
218
+ # class Company
219
+ # validates_presence_of :name, :address, :email
220
+ # validates_length_of :name, :in => 5..30
221
+ # end
222
+ #
223
+ # company = Company.create(:address => '123 First St.')
224
+ # company.hints.full_messages # =>
225
+ # ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Email can't be blank"]
226
+ def full_messages
227
+ map { |attribute, message| full_message(attribute, message) }
228
+ end
229
+
230
+ # Returns a full message for a given attribute.
231
+ #
232
+ # company.hints.full_message(:name, "is invalid") # =>
233
+ # "Name is invalid"
234
+ def full_message(attribute, message)
235
+ return message if attribute == :base
236
+ attr_name = attribute.to_s.gsub('.', '_').humanize
237
+ attr_name = @base.class.human_attribute_name(attribute, :default => attr_name)
238
+ I18n.t(:"hints.format", {
239
+ :default => "%{attribute} %{message}",
240
+ :attribute => attr_name,
241
+ :message => message
242
+ })
243
+ end
244
+
45
245
  def validation_hints_for(attribute)
46
246
  result = Array.new
47
247
  @base.class.validators_on(attribute).map do |v|
48
- puts "** ** ** ** V " + v.class.to_s.split('::').last.downcase.gsub('validator','')
248
+ # puts "** ** ** ** V " + v.class.to_s.split('::').last.downcase.gsub('validator','')
49
249
  # check for validators that have no options
50
250
  validator = v.class.to_s.split('::').last.downcase.gsub('validator','')
51
251
  if MESSAGES_FOR_VALIDATORS.include?(validator)
52
252
  result << generate_message(attribute, validator)
53
253
  end
54
254
  v.options.each do |o|
55
- puts "** ** ** ** O " + o.inspect
255
+ # puts "** ** ** ** O " + o.inspect
56
256
  if MESSAGES_FOR_OPTIONS.include?(o.first.to_s)
57
257
  result << generate_message(attribute, [ validator, o.first.to_s ].join('.'), { :count => o.last } )
58
258
  end
59
259
  end
60
260
  end
61
-
62
- # key = v.class.to_s.underscore.gsub('/','.')
63
- # puts "************#{v.inspect}"
64
- # key = [v.qualifier, key].join('.') if v.respond_to?(:qualifier)
65
- # [ key, v.options.except(*CALLBACKS_OPTIONS).keys.map do |o|
66
- # key + "." + o.to_s
67
- # end ].flatten
68
261
  result
69
262
  end
70
263
 
71
264
  def generate_message(attribute, type, options = {})
72
-
73
265
  if @base.class.respond_to?(:i18n_scope)
74
266
  defaults = @base.class.lookup_ancestors.map do |klass|
75
267
  [ :"#{@base.class.i18n_scope}.hints.models.#{klass.model_name.i18n_key}.attributes.#{attribute}.#{type}",
@@ -93,12 +285,10 @@ module ActiveModel
93
285
  :model => @base.class.model_name.human,
94
286
  :attribute => @base.class.human_attribute_name(attribute),
95
287
  }.merge(options)
96
- puts "*" + File.basename(__FILE__) + ": " + "ATTR #{attribute}, OPTIONS #{options.inspect} "
97
- # [ key, options ]
288
+ # puts "*" + File.basename(__FILE__) + ": " + "ATTR #{attribute}, OPTIONS #{options.inspect} "
98
289
  I18n.translate(key, options)
99
290
  end
100
291
 
101
-
102
292
  end
103
293
 
104
294
  end
@@ -1,4 +1,4 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module ValidationHints
3
- VERSION = "0.0.6"
3
+ VERSION = "0.0.7"
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: validation_hints
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: