ccls-common_lib 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.rdoc +116 -0
- data/lib/ccls-common_lib.rb +1 -0
- data/lib/common_lib.rb +37 -0
- data/lib/common_lib/action_controller_extension.rb +8 -0
- data/lib/common_lib/action_controller_extension/accessible_via_protocol.rb +405 -0
- data/lib/common_lib/action_controller_extension/accessible_via_user.rb +605 -0
- data/lib/common_lib/action_controller_extension/routing.rb +20 -0
- data/lib/common_lib/action_controller_extension/test_case.rb +22 -0
- data/lib/common_lib/action_view_extension.rb +3 -0
- data/lib/common_lib/action_view_extension/base.rb +310 -0
- data/lib/common_lib/action_view_extension/form_builder.rb +197 -0
- data/lib/common_lib/active_model.rb +4 -0
- data/lib/common_lib/active_model/errors.rb +16 -0
- data/lib/common_lib/active_model/validations/absence.rb +78 -0
- data/lib/common_lib/active_model/validations/complete_date.rb +138 -0
- data/lib/common_lib/active_model/validations/past_date.rb +121 -0
- data/lib/common_lib/active_record.rb +1 -0
- data/lib/common_lib/active_record/base.rb +129 -0
- data/lib/common_lib/active_support_extension.rb +12 -0
- data/lib/common_lib/active_support_extension/assertions.rb +108 -0
- data/lib/common_lib/active_support_extension/associations.rb +154 -0
- data/lib/common_lib/active_support_extension/attributes.rb +296 -0
- data/lib/common_lib/active_support_extension/pending.rb +115 -0
- data/lib/common_lib/active_support_extension/test_case.rb +203 -0
- data/lib/common_lib/railtie.rb +48 -0
- data/lib/common_lib/ruby.rb +8 -0
- data/lib/common_lib/ruby/array.rb +128 -0
- data/lib/common_lib/ruby/fixnum.rb +5 -0
- data/lib/common_lib/ruby/hash.rb +51 -0
- data/lib/common_lib/ruby/integer.rb +11 -0
- data/lib/common_lib/ruby/nil_class.rb +13 -0
- data/lib/common_lib/ruby/numeric.rb +0 -0
- data/lib/common_lib/ruby/object.rb +53 -0
- data/lib/common_lib/ruby/string.rb +20 -0
- data/lib/common_lib/translation_table.rb +129 -0
- data/lib/tasks/common_lib.rake +10 -0
- data/lib/tasks/csv.rake +0 -0
- data/lib/tasks/database.rake +229 -0
- data/lib/tasks/rcov.rake +52 -0
- data/vendor/assets/javascripts/common_lib.js +77 -0
- data/vendor/assets/stylesheets/common_lib.css +71 -0
- metadata +84 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
class ActiveModel::Errors
|
2
|
+
|
3
|
+
def matching?(attribute,message)
|
4
|
+
#>> a.errors.messages[:cbc_report_found]
|
5
|
+
#=> ["is not included in the list"]
|
6
|
+
#>> a.errors.messages[:cbc_report_found].any?{|m| m.match(/include/)}
|
7
|
+
#=> true
|
8
|
+
#>> a.errors.messages[:cbc_report_found].any?{|m| m.match(/inclue/)}
|
9
|
+
#=> false
|
10
|
+
# all keys seem to be converted to symbols? NOT indifferent.
|
11
|
+
self.include?(attribute.to_sym) &&
|
12
|
+
self.messages[attribute.to_sym].any?{|m| m.match(/#{message.to_s}/) }
|
13
|
+
# @messages[attribute.to_sym].any?{|m| m.match(/#{message.to_s}/) }
|
14
|
+
end
|
15
|
+
|
16
|
+
end # ActiveModel::Errors
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# don't think that this is necessary here, but ...
|
2
|
+
require 'active_support/core_ext/object/blank'
|
3
|
+
|
4
|
+
#
|
5
|
+
# This is just a modified version of validates_presence_of
|
6
|
+
#
|
7
|
+
|
8
|
+
module ActiveModel
|
9
|
+
|
10
|
+
# == Active Model Absence Validator
|
11
|
+
module Validations
|
12
|
+
class AbsenceValidator < EachValidator
|
13
|
+
|
14
|
+
def validate(record)
|
15
|
+
[attributes].flatten.each do |attribute|
|
16
|
+
value = record.send(:read_attribute_for_validation, attribute)
|
17
|
+
# associated default error message is in config/locales/en.yml
|
18
|
+
record.errors.add(attribute, :absent, options) unless value.blank?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# def validate(record)
|
23
|
+
# [attributes].flatten.each do |attribute|
|
24
|
+
# value = record.send(:read_attribute_for_validation, attribute)
|
25
|
+
#
|
26
|
+
## same thing since :read_attribute_for_validation is an alias for :send
|
27
|
+
## which is technically record.send(:send,attribute) which is the same as ...
|
28
|
+
#
|
29
|
+
#
|
30
|
+
## TODO
|
31
|
+
## custom validation messages don't seem to be making it through.
|
32
|
+
## i think I need to add something in the locales and pass a symbol that finds the default.
|
33
|
+
## Still not sure
|
34
|
+
#
|
35
|
+
#
|
36
|
+
## value = record.send(attribute)
|
37
|
+
## record.errors.add(attribute, "is present and must be absent.", options) unless value.blank?
|
38
|
+
# # associated default error message is in config/locales/en.yml
|
39
|
+
# record.errors.add(attribute, :absent, options) unless value.blank?
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
module HelperMethods
|
46
|
+
# Validates that the specified attributes are blank (as defined by Object#blank?). Happens by default on save. Example:
|
47
|
+
#
|
48
|
+
# class Person < ActiveRecord::Base
|
49
|
+
# validates_absence_of :first_name
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# The first_name attribute must be in the object and it cannot be blank.
|
53
|
+
#
|
54
|
+
# If you want to validate the absence of a boolean field (where the real values are true and false),
|
55
|
+
# you will want to use <tt>validates_inclusion_of :field_name, :in => [true, false]</tt>.
|
56
|
+
#
|
57
|
+
# This is due to the way Object#blank? handles boolean values: <tt>false.blank? # => true</tt>.
|
58
|
+
#
|
59
|
+
# Configuration options:
|
60
|
+
# * <tt>:message</tt> - A custom error message (default is: "can't be blank").
|
61
|
+
# * <tt>:on</tt> - Specifies when this validation is active. Runs in all
|
62
|
+
# validation contexts by default (+nil+), other options are <tt>:create</tt>
|
63
|
+
# and <tt>:update</tt>.
|
64
|
+
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
|
65
|
+
# occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>).
|
66
|
+
# The method, proc or string should return or evaluate to a true or false value.
|
67
|
+
# * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
68
|
+
# not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>).
|
69
|
+
# The method, proc or string should return or evaluate to a true or false value.
|
70
|
+
# * <tt>:strict</tt> - Specifies whether validation should be strict.
|
71
|
+
# See <tt>ActiveModel::Validation#validates!</tt> for more information
|
72
|
+
#
|
73
|
+
def validates_absence_of(*attr_names)
|
74
|
+
validates_with AbsenceValidator, _merge_attributes(attr_names)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# don't think that this is necessary here, but ...
|
2
|
+
require 'active_support/core_ext/object/blank'
|
3
|
+
|
4
|
+
#
|
5
|
+
# This is just a modified version of validates_presence_of
|
6
|
+
#
|
7
|
+
# I think that this validation inherently is allow_blank => true
|
8
|
+
#
|
9
|
+
|
10
|
+
module ActiveModel
|
11
|
+
|
12
|
+
# == Active Model Complete Date Validator
|
13
|
+
module Validations
|
14
|
+
class CompleteDateValidator < EachValidator
|
15
|
+
def validate(record)
|
16
|
+
[attributes].flatten.each do |attribute|
|
17
|
+
value = record.send("#{attribute}_before_type_cast")
|
18
|
+
if( value.is_a?(String) and !value.blank? )
|
19
|
+
date_hash = Date._parse(value)
|
20
|
+
# >> Date._parse( '1/10/2011')
|
21
|
+
# => {:mon=>1, :year=>2011, :mday=>10}
|
22
|
+
unless date_hash.has_key?(:year) &&
|
23
|
+
date_hash.has_key?(:mon) &&
|
24
|
+
date_hash.has_key?(:mday)
|
25
|
+
# associated default error message is in config/locales/en.yml
|
26
|
+
record.errors.add(attribute, :incomplete_date, options)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# def validate(record)
|
33
|
+
# [attributes].flatten.each do |attribute|
|
34
|
+
#
|
35
|
+
##
|
36
|
+
## This doesn't work correctly for DateTimes
|
37
|
+
##
|
38
|
+
## Apparently, DateTimes are immediately typecast.
|
39
|
+
## It either is valid or isn't. PERIOD.
|
40
|
+
##
|
41
|
+
## I can raise an error that the given datetime was incomplete,
|
42
|
+
## but when it is re-presented to the user, it will be complete.
|
43
|
+
##
|
44
|
+
## for datetime
|
45
|
+
##BEFORE TC:03/2012
|
46
|
+
##AFTER TC:2012-03-01 00:00:00 -0800
|
47
|
+
##
|
48
|
+
## for date
|
49
|
+
##BEFORE TC:03/2012
|
50
|
+
##AFTER TC:
|
51
|
+
#
|
52
|
+
## partial datetimes will actually have the attribute set to a full datetime
|
53
|
+
## with the defaults of 0s or 1s filled in.
|
54
|
+
## partial dates will NOT. Why the difference? ERRRRRR
|
55
|
+
##
|
56
|
+
## for both, however, the text field in view will correctly retain the
|
57
|
+
## before_type_cast partial input? Yay, I guess. Confused, definitely.
|
58
|
+
##
|
59
|
+
#
|
60
|
+
#
|
61
|
+
## my fake attributes don't have _before_type_cast, because that's what they are
|
62
|
+
#
|
63
|
+
#
|
64
|
+
#
|
65
|
+
## value = record.send(:read_attribute_for_validation, attribute)
|
66
|
+
# # I really want the before_type_cast
|
67
|
+
# value = record.send("#{attribute}_before_type_cast")
|
68
|
+
#
|
69
|
+
#
|
70
|
+
#
|
71
|
+
## value = if record.methods.include?("#{attribute}_before_type_cast")
|
72
|
+
## record.send("#{attribute}_before_type_cast")
|
73
|
+
## else
|
74
|
+
## record.send("#{attribute}")
|
75
|
+
## end
|
76
|
+
#
|
77
|
+
#
|
78
|
+
##
|
79
|
+
## shouldn't the allow_nil and allow_blank features actually
|
80
|
+
## be dealt with already? actually no, that's in the add method
|
81
|
+
## but we can't get that far as will fail if nil
|
82
|
+
##
|
83
|
+
## unless( options[:allow_nil] && value.nil? ) ||
|
84
|
+
## ( options[:allow_blank] && value.blank? ) ||
|
85
|
+
## ( !value.is_a?(String) )
|
86
|
+
#
|
87
|
+
#
|
88
|
+
## unless( !value.is_a?(String) )
|
89
|
+
# if( value.is_a?(String) and !valid.blank? )
|
90
|
+
# date_hash = Date._parse(value)
|
91
|
+
# # >> Date._parse( '1/10/2011')
|
92
|
+
# # => {:mon=>1, :year=>2011, :mday=>10}
|
93
|
+
# unless date_hash.has_key?(:year) &&
|
94
|
+
# date_hash.has_key?(:mon) &&
|
95
|
+
# date_hash.has_key?(:mday)
|
96
|
+
# # associated default error message is in config/locales/en.yml
|
97
|
+
# record.errors.add(attribute, :incomplete_date, options)
|
98
|
+
# end
|
99
|
+
# end
|
100
|
+
# end
|
101
|
+
# end
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
module HelperMethods
|
106
|
+
# Validates that the specified attributes contain a complete date. Happens by default on save. Example:
|
107
|
+
#
|
108
|
+
# class Person < ActiveRecord::Base
|
109
|
+
# validates_complete_date_for :dob
|
110
|
+
# end
|
111
|
+
#
|
112
|
+
# The first_name attribute must be in the object and it cannot be blank.
|
113
|
+
#
|
114
|
+
# If you want to validate the absence of a boolean field (where the real values are true and false),
|
115
|
+
# you will want to use <tt>validates_inclusion_of :field_name, :in => [true, false]</tt>.
|
116
|
+
#
|
117
|
+
# This is due to the way Object#blank? handles boolean values: <tt>false.blank? # => true</tt>.
|
118
|
+
#
|
119
|
+
# Configuration options:
|
120
|
+
# * <tt>:message</tt> - A custom error message (default is: "can't be blank").
|
121
|
+
# * <tt>:on</tt> - Specifies when this validation is active. Runs in all
|
122
|
+
# validation contexts by default (+nil+), other options are <tt>:create</tt>
|
123
|
+
# and <tt>:update</tt>.
|
124
|
+
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
|
125
|
+
# occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>).
|
126
|
+
# The method, proc or string should return or evaluate to a true or false value.
|
127
|
+
# * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
128
|
+
# not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>).
|
129
|
+
# The method, proc or string should return or evaluate to a true or false value.
|
130
|
+
# * <tt>:strict</tt> - Specifies whether validation should be strict.
|
131
|
+
# See <tt>ActiveModel::Validation#validates!</tt> for more information
|
132
|
+
#
|
133
|
+
def validates_complete_date_for(*attr_names)
|
134
|
+
validates_with CompleteDateValidator, _merge_attributes(attr_names)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# don't think that this is necessary here, but ...
|
2
|
+
require 'active_support/core_ext/object/blank'
|
3
|
+
|
4
|
+
#
|
5
|
+
# This is just a modified version of validates_presence_of
|
6
|
+
#
|
7
|
+
# I think that this validation inherently is allow_blank => true
|
8
|
+
#
|
9
|
+
|
10
|
+
module ActiveModel
|
11
|
+
|
12
|
+
# == Active Model Past Date Validator
|
13
|
+
module Validations
|
14
|
+
class PastDateValidator < EachValidator
|
15
|
+
def validate(record)
|
16
|
+
[attributes].flatten.each do |attribute|
|
17
|
+
# value = record.send(attribute)
|
18
|
+
value = record.send(:read_attribute_for_validation, attribute)
|
19
|
+
|
20
|
+
allow_today = ( options.has_key?(:allow_today) ) ? options[:allow_today] : true
|
21
|
+
|
22
|
+
base_date = if value.is_a?(ActiveSupport::TimeWithZone)
|
23
|
+
# puts "Comparing #{attribute} as ActiveSupport::TimeWithZone"
|
24
|
+
( allow_today ) ? Time.zone.now : ( Time.zone.now - 1.day )
|
25
|
+
elsif value.is_a?(DateTime)
|
26
|
+
# puts "Comparing #{attribute} as DateTime"
|
27
|
+
( allow_today ) ? Time.now : ( Time.now - 1.day )
|
28
|
+
else
|
29
|
+
# puts "Comparing #{attribute} as Date"
|
30
|
+
( allow_today ) ? Date.current : Date.yesterday
|
31
|
+
end
|
32
|
+
if !value.blank? && value > base_date
|
33
|
+
# associated default error message is in config/locales/en.yml
|
34
|
+
record.errors.add(attribute, :future_date, options)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# def validate(record)
|
40
|
+
# [attributes].flatten.each do |attribute|
|
41
|
+
## value = record.send(attribute)
|
42
|
+
# value = record.send(:read_attribute_for_validation, attribute)
|
43
|
+
#
|
44
|
+
##
|
45
|
+
## Do this differenly for Dates and DateTimes?
|
46
|
+
## How to know what it is when the value is blank?
|
47
|
+
##
|
48
|
+
# allow_today = ( options.has_key?(:allow_today) ) ? options[:allow_today] : true
|
49
|
+
#
|
50
|
+
# base_date = if value.is_a?(ActiveSupport::TimeWithZone)
|
51
|
+
##puts "Comparing as ActiveSupport::TimeWithZone"
|
52
|
+
# ( allow_today ) ? Time.zone.now : ( Time.zone.now - 1.day )
|
53
|
+
# elsif value.is_a?(DateTime)
|
54
|
+
##puts "Comparing as DateTime"
|
55
|
+
# ( allow_today ) ? Time.now : ( Time.now - 1.day )
|
56
|
+
# else
|
57
|
+
##puts "Comparing as Date"
|
58
|
+
# ( allow_today ) ? Date.current : Date.yesterday
|
59
|
+
# end
|
60
|
+
## usually dates
|
61
|
+
##Sample @@ should allow collected_at to be today: Comparing as Date
|
62
|
+
##Comparing as Date
|
63
|
+
##Comparing as Date
|
64
|
+
##Comparing as Date
|
65
|
+
##Comparing as ActiveSupport::TimeWithZone
|
66
|
+
##Comparing as Date
|
67
|
+
##Comparing as Date
|
68
|
+
##Comparing as Date
|
69
|
+
##Comparing as Date
|
70
|
+
##Comparing as Date
|
71
|
+
#
|
72
|
+
#
|
73
|
+
##
|
74
|
+
## if base_date is a date and value is a DateTime
|
75
|
+
## ArgumentError: comparison of Date with ActiveSupport::TimeWithZone failed
|
76
|
+
##
|
77
|
+
#
|
78
|
+
## if !value.blank? && base_date < value
|
79
|
+
# if !value.blank? && value > base_date
|
80
|
+
## record.errors.add(attribute, "is in the future and must be in the past.", options)
|
81
|
+
# # associated default error message is in config/locales/en.yml
|
82
|
+
# record.errors.add(attribute, :future_date, options)
|
83
|
+
# end
|
84
|
+
# end
|
85
|
+
# end
|
86
|
+
end
|
87
|
+
|
88
|
+
module HelperMethods
|
89
|
+
# Validates that the specified attributes contain a date in the past. Happens by default on save. Example:
|
90
|
+
#
|
91
|
+
# class Person < ActiveRecord::Base
|
92
|
+
# validates_past_date_for :dob
|
93
|
+
# end
|
94
|
+
#
|
95
|
+
# The first_name attribute must be in the object and it cannot be blank.
|
96
|
+
#
|
97
|
+
# If you want to validate the absence of a boolean field (where the real values are true and false),
|
98
|
+
# you will want to use <tt>validates_inclusion_of :field_name, :in => [true, false]</tt>.
|
99
|
+
#
|
100
|
+
# This is due to the way Object#blank? handles boolean values: <tt>false.blank? # => true</tt>.
|
101
|
+
#
|
102
|
+
# Configuration options:
|
103
|
+
# * <tt>:message</tt> - A custom error message (default is: "can't be blank").
|
104
|
+
# * <tt>:on</tt> - Specifies when this validation is active. Runs in all
|
105
|
+
# validation contexts by default (+nil+), other options are <tt>:create</tt>
|
106
|
+
# and <tt>:update</tt>.
|
107
|
+
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
|
108
|
+
# occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>).
|
109
|
+
# The method, proc or string should return or evaluate to a true or false value.
|
110
|
+
# * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
111
|
+
# not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>).
|
112
|
+
# The method, proc or string should return or evaluate to a true or false value.
|
113
|
+
# * <tt>:strict</tt> - Specifies whether validation should be strict.
|
114
|
+
# See <tt>ActiveModel::Validation#validates!</tt> for more information
|
115
|
+
#
|
116
|
+
def validates_past_date_for(*attr_names)
|
117
|
+
validates_with PastDateValidator, _merge_attributes(attr_names)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'common_lib/active_record/base'
|
@@ -0,0 +1,129 @@
|
|
1
|
+
class ActiveRecord::Base
|
2
|
+
|
3
|
+
#
|
4
|
+
# I have found that the validations are really cluttering up the models.
|
5
|
+
# Moving them into a yml file and pulling them in like so seems to
|
6
|
+
# be working well.
|
7
|
+
#
|
8
|
+
# Not all validations are going to work, but so far so good.
|
9
|
+
#
|
10
|
+
# http://codereview.stackexchange.com/questions/159/use-of-a-regex-stored-inside-yaml-file
|
11
|
+
# email_regex: !ruby/regexp /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i
|
12
|
+
# http://stackoverflow.com/questions/3337020/how-to-specify-ranges-in-yaml
|
13
|
+
# :in: !ruby/range 5..250
|
14
|
+
# http://www.opensource.apple.com/source/ruby/ruby-14/ruby/lib/yaml/rubytypes.rb
|
15
|
+
# http://yaml4r.sourceforge.net/doc/page/objects_in_yaml.htm
|
16
|
+
#
|
17
|
+
# /opt/local/lib/ruby1.9/1.9.1/syck/rubytypes.rb
|
18
|
+
# /opt/local/lib/ruby1.9/1.9.1/psych/visitors/to_ruby.rb
|
19
|
+
#
|
20
|
+
# I really like this and I may very well make it a default at some point.
|
21
|
+
#
|
22
|
+
def self.validations_from_yaml_file
|
23
|
+
validation_file = File.join(Rails.root,"config/validations/#{self.to_s.underscore}.yml")
|
24
|
+
if File.exists?(validation_file)
|
25
|
+
h = YAML::load( ERB.new( IO.read( validation_file )).result)
|
26
|
+
|
27
|
+
# if the yml file is empty, h is false ( added "if h" condition )
|
28
|
+
h.each do |validation|
|
29
|
+
attributes=[validation.delete(:attributes), validation.delete(:attribute)
|
30
|
+
].compact.flatten
|
31
|
+
self.validates *attributes, validation
|
32
|
+
end if h
|
33
|
+
# else
|
34
|
+
# puts "YAML validations file not found so not using."
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.validates_uniqueness_of_with_nilification(*args)
|
39
|
+
# NOTE ANY field that has a unique index in the database NEEDS
|
40
|
+
# to NOT be blank. Multiple nils are acceptable in index,
|
41
|
+
# but multiple blanks are NOT. Nilify ALL fields with
|
42
|
+
# unique indexes in the database. At least those that
|
43
|
+
# would appear on a form, as an empty text box is sent
|
44
|
+
# as '' and not nil, hence the initial problem.
|
45
|
+
# The first one will work, but will fail after.
|
46
|
+
|
47
|
+
# ONLY IF THE FIELD IS A STRING!
|
48
|
+
class_eval do
|
49
|
+
validates_uniqueness_of args, :allow_blank => true
|
50
|
+
args.each do |arg|
|
51
|
+
before_validation {
|
52
|
+
self.send("#{arg}=", nil) if self.send(arg).blank?
|
53
|
+
}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.nilify_if_blank(*args)
|
59
|
+
# ONLY IF THE FIELD IS A STRING!
|
60
|
+
class_eval do
|
61
|
+
args.each do |arg|
|
62
|
+
before_save {
|
63
|
+
self.send("#{arg}=", nil) if self.send(arg).blank?
|
64
|
+
}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.acts_like_a_hash(*args)
|
70
|
+
options = {
|
71
|
+
:key => :key,
|
72
|
+
:value => :description
|
73
|
+
}.update(args.extract_options!)
|
74
|
+
|
75
|
+
cattr_accessor :acts_like_a_hash_options
|
76
|
+
cattr_accessor :acts_like_a_hash_memory
|
77
|
+
|
78
|
+
class_eval do
|
79
|
+
|
80
|
+
self.acts_like_a_hash_options = options
|
81
|
+
self.acts_like_a_hash_memory = {}
|
82
|
+
|
83
|
+
validates_presence_of options[:key], options[:value]
|
84
|
+
validates_uniqueness_of options[:key], options[:value]
|
85
|
+
validates_length_of options[:key], options[:value],
|
86
|
+
:maximum => 250, :allow_blank => true
|
87
|
+
|
88
|
+
# Treats the class a bit like a Hash and
|
89
|
+
# searches for a record with a matching key.
|
90
|
+
def self.[](key)
|
91
|
+
self.acts_like_a_hash_memory[key.downcase.to_s] ||=
|
92
|
+
where(self.arel_table[self.acts_like_a_hash_options[:key]].matches(key)).first
|
93
|
+
end
|
94
|
+
|
95
|
+
end # class_eval do
|
96
|
+
end # def acts_like_a_hash(*args)
|
97
|
+
|
98
|
+
def self.random
|
99
|
+
count = count()
|
100
|
+
if count > 0
|
101
|
+
offset(rand(count)).limit(1).first
|
102
|
+
else
|
103
|
+
nil
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
# for those classes that don't use the feature, just add the method.
|
109
|
+
def self.aliased_attributes
|
110
|
+
{}
|
111
|
+
end
|
112
|
+
|
113
|
+
# cattr_accessor here would create a class variable for ActiveRecord::Base
|
114
|
+
# What I want is the subclass to have one so just wait until its used the first time
|
115
|
+
# and create the class variable them
|
116
|
+
# cattr_accessor :aliased_attributes
|
117
|
+
def self.alias_attribute_with_memory(new_name, old_name)
|
118
|
+
unless self.class_variable_defined? '@@aliased_attributes'
|
119
|
+
cattr_accessor :aliased_attributes
|
120
|
+
self.aliased_attributes = {}.with_indifferent_access
|
121
|
+
end
|
122
|
+
self.aliased_attributes[new_name] = old_name
|
123
|
+
alias_attribute_without_memory(new_name, old_name)
|
124
|
+
end
|
125
|
+
class << self
|
126
|
+
alias_method_chain :alias_attribute, :memory
|
127
|
+
end
|
128
|
+
|
129
|
+
end # class ActiveRecord::Base
|