setting_accessors 0.3.0 → 1.0.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 +5 -5
- data/.editorconfig +10 -0
- data/.rspec +1 -0
- data/.rubocop.yml +131 -0
- data/.travis.yml +11 -7
- data/Appraisals +17 -0
- data/CHANGELOG.md +38 -1
- data/Gemfile +2 -0
- data/README.md +64 -124
- data/Rakefile +5 -27
- data/bin/console +15 -0
- data/bin/setup +10 -0
- data/gemfiles/rails_4.1.gemfile +7 -0
- data/gemfiles/rails_4.2.gemfile +7 -0
- data/gemfiles/rails_4.2.gemfile.lock +162 -0
- data/gemfiles/rails_5.0.gemfile +7 -0
- data/gemfiles/rails_5.0.gemfile.lock +169 -0
- data/gemfiles/rails_5.1.gemfile +7 -0
- data/gemfiles/rails_5.1.gemfile.lock +169 -0
- data/gemfiles/rails_5.2.gemfile +7 -0
- data/gemfiles/rails_5.2.gemfile.lock +177 -0
- data/lib/generators/setting_accessors/install_generator.rb +11 -9
- data/lib/generators/setting_accessors/templates/model.rb.erb +0 -24
- data/lib/setting_accessors.rb +14 -5
- data/lib/setting_accessors/accessor_generator.rb +66 -0
- data/lib/setting_accessors/converters/base.rb +24 -0
- data/lib/setting_accessors/converters/boolean_converter.rb +51 -0
- data/lib/setting_accessors/converters/integer_converter.rb +21 -0
- data/lib/setting_accessors/converters/polymorphic_converter.rb +11 -0
- data/lib/setting_accessors/converters/string_converter.rb +11 -0
- data/lib/setting_accessors/helpers.rb +28 -0
- data/lib/setting_accessors/integration.rb +83 -97
- data/lib/setting_accessors/internal.rb +37 -64
- data/lib/setting_accessors/setting_scaffold.rb +147 -214
- data/lib/setting_accessors/setting_set.rb +168 -0
- data/lib/setting_accessors/version.rb +3 -1
- data/lib/tasks/setting_accessors_tasks.rake +2 -0
- data/setting_accessors.gemspec +27 -19
- metadata +117 -143
- data/.codeclimate.yml +0 -66
- data/lib/setting_accessors/accessor.rb +0 -189
- data/lib/setting_accessors/converter.rb +0 -71
- data/lib/setting_accessors/integration_validator.rb +0 -15
- data/lib/setting_accessors/validator.rb +0 -144
- data/test/dummy/README.rdoc +0 -28
- data/test/dummy/Rakefile +0 -6
- data/test/dummy/app/assets/images/.keep +0 -0
- data/test/dummy/app/assets/javascripts/application.js +0 -13
- data/test/dummy/app/assets/stylesheets/application.css +0 -15
- data/test/dummy/app/controllers/application_controller.rb +0 -5
- data/test/dummy/app/controllers/concerns/.keep +0 -0
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/mailers/.keep +0 -0
- data/test/dummy/app/models/.keep +0 -0
- data/test/dummy/app/models/concerns/.keep +0 -0
- data/test/dummy/app/models/post.rb +0 -2
- data/test/dummy/app/models/setting.rb +0 -59
- data/test/dummy/app/models/user.rb +0 -19
- data/test/dummy/app/views/layouts/application.html.erb +0 -14
- data/test/dummy/bin/bundle +0 -3
- data/test/dummy/bin/rails +0 -4
- data/test/dummy/bin/rake +0 -4
- data/test/dummy/config.ru +0 -4
- data/test/dummy/config/application.rb +0 -25
- data/test/dummy/config/boot.rb +0 -5
- data/test/dummy/config/database.yml +0 -25
- data/test/dummy/config/environment.rb +0 -5
- data/test/dummy/config/environments/development.rb +0 -37
- data/test/dummy/config/environments/production.rb +0 -83
- data/test/dummy/config/environments/test.rb +0 -34
- data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/test/dummy/config/initializers/cookies_serializer.rb +0 -3
- data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -4
- data/test/dummy/config/initializers/inflections.rb +0 -16
- data/test/dummy/config/initializers/mime_types.rb +0 -4
- data/test/dummy/config/initializers/session_store.rb +0 -3
- data/test/dummy/config/initializers/setting_accessors.rb +0 -1
- data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/test/dummy/config/locales/en.yml +0 -23
- data/test/dummy/config/routes.rb +0 -56
- data/test/dummy/config/secrets.yml +0 -22
- data/test/dummy/config/settings.yml +0 -23
- data/test/dummy/db/migrate/20150102112106_create_users.rb +0 -9
- data/test/dummy/db/migrate/20150102115329_create_settings.rb +0 -12
- data/test/dummy/db/migrate/20150723114600_create_posts.rb +0 -11
- data/test/dummy/db/schema.rb +0 -40
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/lib/assets/.keep +0 -0
- data/test/dummy/public/404.html +0 -67
- data/test/dummy/public/422.html +0 -67
- data/test/dummy/public/500.html +0 -66
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/test/fixtures/posts.yml +0 -11
- data/test/dummy/test/models/post_test.rb +0 -19
- data/test/dummy/test/models/setting_test.rb +0 -143
- data/test/dummy/test/models/user_test.rb +0 -154
- data/test/generators/install_generator_test.rb +0 -15
- data/test/setting_accessors_test.rb +0 -4
- data/test/test_helper.rb +0 -31
data/.codeclimate.yml
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
---
|
2
|
-
engines:
|
3
|
-
rubocop:
|
4
|
-
enabled: true
|
5
|
-
eslint:
|
6
|
-
enabled: true
|
7
|
-
csslint:
|
8
|
-
enabled: true
|
9
|
-
ratings:
|
10
|
-
paths:
|
11
|
-
- "**.rb"
|
12
|
-
- "**.js"
|
13
|
-
- "**.jsx"
|
14
|
-
- "**.css"
|
15
|
-
exclude_paths:
|
16
|
-
- test/**/*
|
17
|
-
# This is a sample .codeclimate.yml configured for Engine analysis on Code
|
18
|
-
# Climate Platform. For an overview of the Code Climate Platform, see here:
|
19
|
-
# http://docs.codeclimate.com/article/300-the-codeclimate-platform
|
20
|
-
|
21
|
-
# Under the engines key, you can configure which engines will analyze your repo.
|
22
|
-
# Each key is an engine name. For each value, you need to specify enabled: true
|
23
|
-
# to enable the engine as well as any other engines-specific configuration.
|
24
|
-
|
25
|
-
# For more details, see here:
|
26
|
-
# http://docs.codeclimate.com/article/289-configuring-your-repository-via-codeclimate-yml#platform
|
27
|
-
|
28
|
-
# For a list of all available engines, see here:
|
29
|
-
# http://docs.codeclimate.com/article/296-engines-available-engines
|
30
|
-
|
31
|
-
engines:
|
32
|
-
# to turn on an engine, add it here and set enabled to `true`
|
33
|
-
# to turn off an engine, set enabled to `false` or remove it
|
34
|
-
rubocop:
|
35
|
-
enabled: true
|
36
|
-
golint:
|
37
|
-
enabled: true
|
38
|
-
gofmt:
|
39
|
-
enabled: true
|
40
|
-
eslint:
|
41
|
-
enabled: true
|
42
|
-
csslint:
|
43
|
-
enabled: true
|
44
|
-
|
45
|
-
# Engines can analyze files and report issues on them, but you can separately
|
46
|
-
# decide which files will receive ratings based on those issues. This is
|
47
|
-
# specified by path patterns under the ratings key.
|
48
|
-
|
49
|
-
# For more details see here:
|
50
|
-
# http://docs.codeclimate.com/article/289-configuring-your-repository-via-codeclimate-yml#platform
|
51
|
-
|
52
|
-
# Note: If the ratings key is not specified, this will result in a 0.0 GPA on your dashboard.
|
53
|
-
|
54
|
-
# ratings:
|
55
|
-
# paths:
|
56
|
-
# - app/**
|
57
|
-
# - lib/**
|
58
|
-
# - "**.rb"
|
59
|
-
# - "**.go"
|
60
|
-
|
61
|
-
# You can globally exclude files from being analyzed by any engine using the
|
62
|
-
# exclude_paths key.
|
63
|
-
|
64
|
-
#exclude_paths:
|
65
|
-
#- spec/**/*
|
66
|
-
#- vendor/**/*
|
@@ -1,189 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Helper class to make accessing record specific settings easier
|
3
|
-
#
|
4
|
-
class SettingAccessors::Accessor
|
5
|
-
|
6
|
-
def initialize(record)
|
7
|
-
@record = record
|
8
|
-
@temp_settings = {}
|
9
|
-
end
|
10
|
-
|
11
|
-
#
|
12
|
-
# Tries to retrieve the given setting's value from the temp settings
|
13
|
-
# (already read/written values in this instance). If the setting hasn't been
|
14
|
-
# used before, its value is retrieved from the database.
|
15
|
-
#
|
16
|
-
# If a setting hasn't been read by this record (instance) before, its value
|
17
|
-
# is stored in the local read set.
|
18
|
-
#
|
19
|
-
# TODO: See if this causes problems with read settings not being updated by external changes.
|
20
|
-
# User1: Read Setting X
|
21
|
-
# User2: Update Setting X
|
22
|
-
# User1: Read Setting X -> Gets old value from temp settings.
|
23
|
-
# This shouldn't be too dangerous as the system state will be refreshed with every request though.
|
24
|
-
#
|
25
|
-
def [](key)
|
26
|
-
return @temp_settings[key.to_sym] if has_key?(key)
|
27
|
-
value = SettingAccessors.setting_class.get(key, @record)
|
28
|
-
@temp_settings[key.to_sym] = value unless value.nil?
|
29
|
-
value
|
30
|
-
end
|
31
|
-
|
32
|
-
#
|
33
|
-
# Tries to fetch a setting value using the provided key and #[].
|
34
|
-
# It will only return the +default+ value if there is
|
35
|
-
# - no temporary setting with the given key AND
|
36
|
-
# - no already persisted setting (see #[])
|
37
|
-
#
|
38
|
-
def fetch(key, default = nil)
|
39
|
-
result = self[key]
|
40
|
-
return default if result.nil? && !has_key?(key)
|
41
|
-
result
|
42
|
-
end
|
43
|
-
|
44
|
-
#
|
45
|
-
# Like #fetch, but it will store the default value as a temporary setting
|
46
|
-
# if no actual setting value could be found. This is useful to further work
|
47
|
-
# with default setting values.
|
48
|
-
# The default value is cloned (using #dup to avoid copying object states) before
|
49
|
-
# it is assigned. This will not work for singleton instances like true, false, etc.
|
50
|
-
#
|
51
|
-
def fetch_and_store(key, default = nil)
|
52
|
-
result = self[key]
|
53
|
-
if result.nil? && !has_key?(key)
|
54
|
-
self[key] = default.duplicable? ? default.dup : default
|
55
|
-
else
|
56
|
-
result
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def has_key?(key)
|
61
|
-
@temp_settings.has_key?(key.to_sym)
|
62
|
-
end
|
63
|
-
|
64
|
-
#
|
65
|
-
# Writes a setting's value
|
66
|
-
#
|
67
|
-
def []=(key, val)
|
68
|
-
set_value_before_type_cast(key, val)
|
69
|
-
@temp_settings[key.to_sym] = SettingAccessors::Internal.converter(value_type(key)).convert(val)
|
70
|
-
end
|
71
|
-
|
72
|
-
#
|
73
|
-
# Tries to find a setting for this record.
|
74
|
-
# If none is found, will return the default setting value
|
75
|
-
# specified in the setting config file.
|
76
|
-
#
|
77
|
-
def get_or_default(key)
|
78
|
-
fetch_and_store(key, SettingAccessors.setting_class.get_or_default(key, @record))
|
79
|
-
end
|
80
|
-
|
81
|
-
#
|
82
|
-
# Tries to find a setting for this record first.
|
83
|
-
# If none is found, tries to find a global setting with the same name
|
84
|
-
#
|
85
|
-
def get_or_global(key)
|
86
|
-
fetch_and_store(key, SettingAccessors.setting_class.get(key))
|
87
|
-
end
|
88
|
-
|
89
|
-
#
|
90
|
-
# Tries to find a setting for this record first,
|
91
|
-
# if none is found, it will return the given value instead.
|
92
|
-
#
|
93
|
-
def get_or_value(key, value)
|
94
|
-
fetch_and_store(key, value)
|
95
|
-
end
|
96
|
-
|
97
|
-
def get_with_fallback(key, fallback = nil)
|
98
|
-
return self[key] if fallback.nil?
|
99
|
-
|
100
|
-
case fallback.to_s
|
101
|
-
when 'default' then get_or_default(key)
|
102
|
-
when 'global' then get_or_global(key)
|
103
|
-
else get_or_value(key, fallback)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
#
|
108
|
-
# @return [String] the setting's value type in the +@record+'s context
|
109
|
-
#
|
110
|
-
def value_type(key)
|
111
|
-
SettingAccessors::Internal.setting_value_type(key, @record)
|
112
|
-
end
|
113
|
-
|
114
|
-
#----------------------------------------------------------------
|
115
|
-
# ActiveRecord Helper Methods Emulation
|
116
|
-
#----------------------------------------------------------------
|
117
|
-
|
118
|
-
def value_was(key, fallback = nil)
|
119
|
-
return SettingAccessors.setting_class.get(key, @record) if fallback.nil?
|
120
|
-
|
121
|
-
case fallback.to_s
|
122
|
-
when 'default' then SettingAccessors.setting_class.get_or_default(key, @record)
|
123
|
-
when 'global' then SettingAccessors.setting_class.get(key)
|
124
|
-
else fallback
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def value_changed?(key)
|
129
|
-
self[key] != value_was(key)
|
130
|
-
end
|
131
|
-
|
132
|
-
def value_before_type_cast(key)
|
133
|
-
SettingAccessors::Internal.lookup_nested_hash(@values_before_type_casts, key.to_s) || self[key]
|
134
|
-
end
|
135
|
-
|
136
|
-
protected
|
137
|
-
|
138
|
-
#
|
139
|
-
# Keeps a record of the originally set value for a setting before it was
|
140
|
-
# automatically converted.
|
141
|
-
#
|
142
|
-
def set_value_before_type_cast(key, value)
|
143
|
-
@values_before_type_casts ||= {}
|
144
|
-
@values_before_type_casts[key.to_s] = value
|
145
|
-
end
|
146
|
-
|
147
|
-
#
|
148
|
-
# Validates the new setting values.
|
149
|
-
# If there is an accessor for the setting, the errors will be
|
150
|
-
# directly forwarded to it, otherwise to :base
|
151
|
-
#
|
152
|
-
# Please do not call this method directly, use the IntegrationValidator
|
153
|
-
# class instead, e.g.
|
154
|
-
#
|
155
|
-
# validates_with SettingAccessors::IntegrationValidator
|
156
|
-
#
|
157
|
-
def validate!
|
158
|
-
@temp_settings.each do |key, value|
|
159
|
-
validation_errors = SettingAccessors.setting_class.validation_errors(key, value, @record)
|
160
|
-
validation_errors.each do |message|
|
161
|
-
if @record.respond_to?("#{key}=")
|
162
|
-
@record.errors.add(key, message)
|
163
|
-
else
|
164
|
-
@record.errors.add :base, :invalid_setting, :name => key, :message => message
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
#
|
171
|
-
# Saves the new setting values into the database
|
172
|
-
# Please note that there is no check if the values changed their
|
173
|
-
# in the meantime.
|
174
|
-
#
|
175
|
-
# Also, this method expects that the settings were validated
|
176
|
-
# before using #validate! and will therefore not perform
|
177
|
-
# validations itself.
|
178
|
-
#
|
179
|
-
def persist!
|
180
|
-
@temp_settings.each do |key, value|
|
181
|
-
Setting.create_or_update(key, value, @record)
|
182
|
-
end
|
183
|
-
flush!
|
184
|
-
end
|
185
|
-
|
186
|
-
def flush!
|
187
|
-
@temp_settings = {}
|
188
|
-
end
|
189
|
-
end
|
@@ -1,71 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# This class hopefully will hopefully one day mimic ActiveRecord's
|
3
|
-
# attribute assigning methods, meaning that a conversion to the column type
|
4
|
-
# is done as soon as a new value is assigned by the programmer.
|
5
|
-
#
|
6
|
-
# If the value cannot be parsed in the required type, +nil+ is assigned.
|
7
|
-
# Please make sure that you specify the correct validations in settings.yml
|
8
|
-
# or assigned model to avoid this.
|
9
|
-
#
|
10
|
-
# Currently supported types:
|
11
|
-
# - Fixnum
|
12
|
-
# - String
|
13
|
-
# - Boolean
|
14
|
-
#
|
15
|
-
# If the type is 'polymorphic', it is not converted at all.
|
16
|
-
#
|
17
|
-
class SettingAccessors::Converter
|
18
|
-
|
19
|
-
def initialize(value_type)
|
20
|
-
@value_type = value_type
|
21
|
-
end
|
22
|
-
|
23
|
-
#
|
24
|
-
# Converts the setting's value to the correct type
|
25
|
-
#
|
26
|
-
def convert(new_value)
|
27
|
-
#If the value is set to be polymorphic, we don't have to convert anything.
|
28
|
-
return new_value if @value_type.to_s == 'polymorphic'
|
29
|
-
|
30
|
-
#ActiveRecord only converts non-nil values to their database type
|
31
|
-
#during assignment
|
32
|
-
return new_value if new_value.nil?
|
33
|
-
|
34
|
-
parse_method = :"parse_#{@value_type}"
|
35
|
-
|
36
|
-
if private_methods.include?(parse_method)
|
37
|
-
send(parse_method, new_value)
|
38
|
-
else
|
39
|
-
Rails.logger.warn("Invalid Setting type: #{@value_type}")
|
40
|
-
new_value
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
def parse_boolean(value)
|
47
|
-
case value
|
48
|
-
when TrueClass, FalseClass
|
49
|
-
value
|
50
|
-
when String
|
51
|
-
return true if %w[true 1].include?(value.downcase)
|
52
|
-
return false if %w[false 0].include?(value.downcase)
|
53
|
-
nil
|
54
|
-
when Fixnum
|
55
|
-
return true if value == 1
|
56
|
-
return false if value.zero?
|
57
|
-
nil
|
58
|
-
else
|
59
|
-
nil
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def parse_integer(value)
|
64
|
-
value.to_i
|
65
|
-
end
|
66
|
-
|
67
|
-
def parse_string(value)
|
68
|
-
value.to_s
|
69
|
-
end
|
70
|
-
|
71
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# This class handles model validations for assigned records, e.g.
|
3
|
-
# if the settings are accessed using the Accessor class in this module.
|
4
|
-
# Only the new temp values are validated using the setting config.
|
5
|
-
#
|
6
|
-
# The main work is still done in the Accessor class, so we don't have
|
7
|
-
# to access its instance variables here, this class acts as a wrapper
|
8
|
-
# for Rails' validation chain
|
9
|
-
#
|
10
|
-
|
11
|
-
class SettingAccessors::IntegrationValidator < ActiveModel::Validator
|
12
|
-
def validate(record)
|
13
|
-
record.settings.send(:validate!)
|
14
|
-
end
|
15
|
-
end
|
@@ -1,144 +0,0 @@
|
|
1
|
-
class SettingAccessors::Validator < ActiveModel::Validator
|
2
|
-
|
3
|
-
def validate(record)
|
4
|
-
record.send(:validations).each do |key, requirement|
|
5
|
-
if key.to_s == 'custom'
|
6
|
-
Array(requirement).each do |validation|
|
7
|
-
run_custom_validation(record, validation)
|
8
|
-
end
|
9
|
-
elsif built_in_validation?(key)
|
10
|
-
send("validate_#{key}", record, requirement)
|
11
|
-
else
|
12
|
-
raise ArgumentError.new("The invalid validation '#{key}' was given in model '#{defining_model(record).to_s}'")
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def defining_model(record)
|
20
|
-
if SettingAccessors::Internal.globally_defined_setting?(record.name) || !record.assignable
|
21
|
-
SettingAccessors.setting_class
|
22
|
-
else
|
23
|
-
record.assignable.class
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
#
|
28
|
-
# Runs a custom validation method
|
29
|
-
# The method may either be a Proc or an instance method in +record+.+class+
|
30
|
-
#
|
31
|
-
def run_custom_validation(record, proc)
|
32
|
-
case proc
|
33
|
-
when Proc
|
34
|
-
proc.call(record)
|
35
|
-
when Symbol
|
36
|
-
if defining_model(record).respond_to?(proc)
|
37
|
-
defining_model(record).send(proc)
|
38
|
-
else
|
39
|
-
raise ArgumentError.new "The method '#{proc}' was set up as validation method in model '#{defining_model(record).name}', but doesn't exist."
|
40
|
-
end
|
41
|
-
else
|
42
|
-
raise ArgumentError.new "An invalid validations method was given ('#{proc}')"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
#
|
47
|
-
# @return [TrueClass, FalseClass] +true+ if the given validation
|
48
|
-
# is a built-in one.
|
49
|
-
#
|
50
|
-
def built_in_validation?(validation_name)
|
51
|
-
private_methods.include?("validate_#{validation_name}".to_sym)
|
52
|
-
end
|
53
|
-
|
54
|
-
#
|
55
|
-
# Validates that the setting's value is given
|
56
|
-
# accepts :allow_blank and :allow_nil as options
|
57
|
-
#
|
58
|
-
def validate_presence(record, requirement)
|
59
|
-
return true unless requirement
|
60
|
-
|
61
|
-
if requirement.is_a?(Hash)
|
62
|
-
if requirement['allow_blank'] && !record.value.nil? ||
|
63
|
-
requirement['allow_nil'] && record.value.nil? ||
|
64
|
-
record.value.present?
|
65
|
-
true
|
66
|
-
else
|
67
|
-
add_error record, :blank
|
68
|
-
false
|
69
|
-
end
|
70
|
-
else
|
71
|
-
add_error_if record.value.nil? || record.value == '', record, :blank
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
#
|
76
|
-
# Validates numericality of the setting's value based on the options given
|
77
|
-
# in settings.yml
|
78
|
-
#
|
79
|
-
def validate_numericality(record, options)
|
80
|
-
#Test if the value is Numeric in any way (float or int)
|
81
|
-
add_error_if(!parse_value_as_numeric(record.value), record, :not_a_number) && return
|
82
|
-
|
83
|
-
#If the validation was set to check for integer values, do that as well
|
84
|
-
add_error_if(options['only_integer'] && !parse_value_as_fixnum(record.value), record, :not_an_integer)
|
85
|
-
end
|
86
|
-
|
87
|
-
#
|
88
|
-
# Validates whether the given value is a valid boolean
|
89
|
-
#
|
90
|
-
def validate_boolean(record, requirement)
|
91
|
-
add_error_if(requirement && parse_value_as_boolean(record.value).nil?, record, :not_a_boolean)
|
92
|
-
end
|
93
|
-
|
94
|
-
#----------------------------------------------------------------
|
95
|
-
# Helper Methods
|
96
|
-
#----------------------------------------------------------------
|
97
|
-
|
98
|
-
def add_error(record, validation, options = {})
|
99
|
-
record.errors.add :value, validation, options
|
100
|
-
end
|
101
|
-
|
102
|
-
def add_error_if(cond, record, validation, options = {})
|
103
|
-
add_error(record, validation, options) if cond
|
104
|
-
cond
|
105
|
-
end
|
106
|
-
|
107
|
-
#
|
108
|
-
# Borrowed from Rails' numericality validator
|
109
|
-
# @return [Float, NilClass] the given String value as a float or nil
|
110
|
-
# if the value was not a valid Numeric
|
111
|
-
#
|
112
|
-
def parse_value_as_numeric(raw_value)
|
113
|
-
Kernel.Float(raw_value) if raw_value !~ /\A0[xX]/
|
114
|
-
rescue ArgumentError, TypeError
|
115
|
-
nil
|
116
|
-
end
|
117
|
-
|
118
|
-
#
|
119
|
-
# Borrowed from Rails' numericality validator
|
120
|
-
#
|
121
|
-
# @return [Fixnum, NilClass] the given String value as an int or nil
|
122
|
-
#
|
123
|
-
def parse_value_as_fixnum(raw_value)
|
124
|
-
raw_value.to_i if raw_value.to_s =~ /\A[+-]?\d+\Z/
|
125
|
-
end
|
126
|
-
|
127
|
-
#
|
128
|
-
# Tries to parse the given value as a boolean value
|
129
|
-
#
|
130
|
-
# @return [TrueClass, FalseClass, NilClass]
|
131
|
-
#
|
132
|
-
def parse_value_as_boolean(raw_value)
|
133
|
-
case raw_value
|
134
|
-
when TrueClass, FalseClass
|
135
|
-
raw_value
|
136
|
-
when String
|
137
|
-
return true if %w[true 1].include?(raw_value.downcase)
|
138
|
-
return false if %w[false 0].include?(raw_value.downcase)
|
139
|
-
nil
|
140
|
-
else
|
141
|
-
nil
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|