validation_hints 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: