ccls-common_lib 1.4.0
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.
- 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
|