setting_accessors 0.3.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|