rails-settings-cached 2.8.3 → 2.9.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 619f840c2f93682aec9caef59cb4a59404ce145fbb3b55e77dc259b0fc5b3abd
4
- data.tar.gz: c2b49addab5c52403dbb0c3f883276b4c06a870ae4466140b876444dcbaf371f
3
+ metadata.gz: 212d83f192f7446ef64cdb9d2217a8dfe9324a1b8c64b2389857ca2997e5f46a
4
+ data.tar.gz: 4a757c45119a1c31d5ce5d4d3a02af47adcd631856c8c3f403bb5303a0ff4e6c
5
5
  SHA512:
6
- metadata.gz: dcefa7f181b49c310ce6aff7bccb85e004c9048488f3a40cd24d0ed29b31d55d76cbfe6678f1c5eaf9ead4c4d84d1565ef1f0a00e04d02ed2fa58c6bfaf4c6dc
7
- data.tar.gz: 585da097235e2bccd5731500a4bb862a8bdfbc9996f9aa11938b9f6d7f0c5a75f2f88b68388a87bc3898496c1562a6fbf3652ac4b0b6b6610b03a1b1b1221fad
6
+ metadata.gz: 29aa302129ae5ee8950137df21d529b60c90cc3b251acf9760c20b857f75be8f4407a9f4ed2ed518646c1baa411c42513bd04886c22e9d8923c36a4962bb74f4
7
+ data.tar.gz: 2f205f829b23ed7d3cf691b9e9c7d6f4ac236b6767bd2240b65fee039390416453bce3a99dfdfeb892e0c8aa29950ecbfa5693dd302fea1ee853e7f671bd1a23
data/README.md CHANGED
@@ -161,6 +161,55 @@ Setting.get_field("default_locale")[:options]
161
161
  => { option_values: %w[en zh-CN jp], help_text: "Bla bla ..." }
162
162
  ```
163
163
 
164
+ ### Custom type for setting
165
+
166
+ > Since: 2.9.0
167
+
168
+ You can write your custom field type by under `RailsSettings::Fields` module.
169
+
170
+ #### For example
171
+
172
+ ```rb
173
+ module RailsSettings
174
+ module Fields
175
+ class YesNo < ::RailsSettings::Fields::Base
176
+ def serialize(value)
177
+ case value
178
+ when true then "YES"
179
+ when false then "NO"
180
+ else raise StandardError, 'invalid value'
181
+ end
182
+ end
183
+
184
+ def deserialize(value)
185
+ case value
186
+ when "YES" then true
187
+ when "NO" then false
188
+ else nil
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end
194
+ ```
195
+
196
+ Now you can use `yes_no` type in you setting:
197
+
198
+ ```rb
199
+ class Setting
200
+ field :custom_item, type: :yes_no, default: 'YES'
201
+ end
202
+ ```
203
+
204
+ ```rb
205
+ irb> Setting.custom_item = 'YES'
206
+ irb> Setting.custom_item
207
+ true
208
+ irb> Setting.custom_item = 'NO'
209
+ irb> Setting.custom_item
210
+ false
211
+ ```
212
+
164
213
  #### Get All defined fields
165
214
 
166
215
  > version 2.7.0+
@@ -8,7 +8,6 @@ module RailsSettings
8
8
  end
9
9
 
10
10
  class Base < ActiveRecord::Base
11
- SEPARATOR_REGEXP = /[\n,;]+/
12
11
  PROTECTED_KEYS = %w[var value]
13
12
  self.table_name = table_name_prefix + "settings"
14
13
 
@@ -55,7 +54,7 @@ module RailsSettings
55
54
  end
56
55
 
57
56
  def get_field(key)
58
- @defined_fields.find { |field| field[:key] == key.to_s } || {}
57
+ @defined_fields.find { |field| field.key == key.to_s }.to_h || {}
59
58
  end
60
59
 
61
60
  def cache_prefix(&block)
@@ -69,15 +68,15 @@ module RailsSettings
69
68
  end
70
69
 
71
70
  def keys
72
- @defined_fields.map { |field| field[:key] }
71
+ @defined_fields.map(&:key)
73
72
  end
74
73
 
75
74
  def editable_keys
76
- @defined_fields.reject { |field| field[:readonly] }.map { |field| field[:key] }
75
+ @defined_fields.reject(&:readonly).map(&:key)
77
76
  end
78
77
 
79
78
  def readonly_keys
80
- @defined_fields.select { |field| field[:readonly] }.map { |field| field[:key] }
79
+ @defined_fields.select(&:readonly).map(&:key)
81
80
  end
82
81
 
83
82
  attr_reader :defined_fields
@@ -89,56 +88,23 @@ module RailsSettings
89
88
 
90
89
  raise ProtectedKeyError.new(key) if PROTECTED_KEYS.include?(key)
91
90
 
91
+ field = ::RailsSettings::Fields::Base.generate(
92
+ scope: @scope, key: key, default: default,
93
+ type: type, readonly: readonly, options: opts,
94
+ separator: separator, parent: self
95
+ )
92
96
  @defined_fields ||= []
93
- @defined_fields << {
94
- scope: @scope,
95
- key: key,
96
- default: default,
97
- type: type || :string,
98
- readonly: readonly.nil? ? false : readonly,
99
- options: opts
100
- }
101
-
102
- if readonly
103
- define_singleton_method(key) do
104
- result = default.is_a?(Proc) ? default.call : default
105
- send(:_convert_string_to_typeof_value, type, result, separator: separator)
106
- end
107
- else
108
- define_singleton_method(key) do
109
- val = send(:_value_of, key)
110
- result = nil
111
- if !val.nil?
112
- result = val
113
- else
114
- result = default
115
- result = default.call if default.is_a?(Proc)
116
- end
117
-
118
- result = send(:_convert_string_to_typeof_value, type, result, separator: separator)
119
-
120
- result
121
- end
122
-
123
- define_singleton_method("#{key}=") do |value|
124
- var_name = key
125
-
126
- record = find_by(var: var_name) || new(var: var_name)
127
- value = send(:_convert_string_to_typeof_value, type, value, separator: separator)
97
+ @defined_fields << field
128
98
 
129
- record.value = value
130
- record.save!
99
+ define_singleton_method(key) { field.read }
131
100
 
132
- value
133
- end
101
+ unless readonly
102
+ define_singleton_method("#{key}=") { |value| field.save!(value: value) }
134
103
 
135
104
  if validates
136
105
  validates[:if] = proc { |item| item.var.to_s == key }
137
106
  send(:validates, key, **validates)
138
-
139
- define_method(:read_attribute_for_validation) do |_key|
140
- self.value
141
- end
107
+ define_method(:read_attribute_for_validation) { |_key| self.value }
142
108
  end
143
109
  end
144
110
 
@@ -156,49 +122,6 @@ module RailsSettings
156
122
  end
157
123
  end
158
124
 
159
- def _convert_string_to_typeof_value(type, value, separator: nil)
160
- return value unless [String, Integer, Float, BigDecimal].include?(value.class)
161
-
162
- case type
163
- when :boolean
164
- ["true", "1", 1, true].include?(value)
165
- when :array
166
- value.split(separator || SEPARATOR_REGEXP).reject { |str| str.empty? }.map(&:strip)
167
- when :hash
168
- value = begin
169
- YAML.safe_load(value).to_h
170
- rescue
171
- {}
172
- end
173
- value.deep_stringify_keys!
174
- ActiveSupport::HashWithIndifferentAccess.new(value)
175
- when :integer
176
- value.to_i
177
- when :float
178
- value.to_f
179
- when :big_decimal
180
- value.to_d
181
- else
182
- value
183
- end
184
- end
185
-
186
- def _value_of(var_name)
187
- unless _table_exists?
188
- # Fallback to default value if table was not ready (before migrate)
189
- puts "WARNING: table: \"#{table_name}\" does not exist or not database connection, `#{name}.#{var_name}` fallback to returns the default value."
190
- return nil
191
- end
192
-
193
- _all_settings[var_name]
194
- end
195
-
196
- def _table_exists?
197
- table_exists?
198
- rescue
199
- false
200
- end
201
-
202
125
  def rails_initialized?
203
126
  Rails.application&.initialized?
204
127
  end
@@ -0,0 +1,17 @@
1
+ module RailsSettings
2
+ module Fields
3
+ class Array < ::RailsSettings::Fields::Base
4
+ def deserialize(value)
5
+ return nil if value.nil?
6
+
7
+ return value unless value.is_a?(::String)
8
+
9
+ value.split(separator).reject(&:empty?).map(&:strip)
10
+ end
11
+
12
+ def serialize(value)
13
+ deserialize(value)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,77 @@
1
+ module RailsSettings
2
+ module Fields
3
+ class Base < Struct.new(:scope, :key, :default, :parent, :readonly, :separator, :type, :options, keyword_init: true)
4
+ SEPARATOR_REGEXP = /[\n,;]+/
5
+
6
+ def initialize(scope:, key:, default:, parent:, readonly:, separator:, type:, options:)
7
+ super
8
+ self.readonly = !!readonly
9
+ self.type ||= :string
10
+ self.separator ||= SEPARATOR_REGEXP
11
+ end
12
+
13
+ def save!(value:)
14
+ serialized_value = serialize(value)
15
+ parent_record = parent.find_by(var: key) || parent.new(var: key)
16
+ parent_record.value = serialized_value
17
+ parent_record.save!
18
+ parent_record.value
19
+ end
20
+
21
+ def saved_value
22
+ return parent.send(:_all_settings)[key] if table_exists?
23
+
24
+ # Fallback to default value if table was not ready (before migrate)
25
+ puts(
26
+ "WARNING: table: \"#{parent.table_name}\" does not exist or not database connection, `#{parent.name}.#{key}` fallback to returns the default value."
27
+ )
28
+ nil
29
+ end
30
+
31
+ def default_value
32
+ default.is_a?(Proc) ? default.call : default
33
+ end
34
+
35
+ def read
36
+ return deserialize(default_value) if readonly || saved_value.nil?
37
+
38
+ deserialize(saved_value)
39
+ end
40
+
41
+ def deserialize(value)
42
+ raise NotImplementedError
43
+ end
44
+
45
+ def serialize(value)
46
+ raise NotImplementedError
47
+ end
48
+
49
+ def to_h
50
+ super.slice(:scope, :key, :default, :type, :readonly, :options)
51
+ end
52
+
53
+ def table_exists?
54
+ parent.table_exists?
55
+ rescue StandardError
56
+ false
57
+ end
58
+
59
+ class << self
60
+ def generate(**args)
61
+ fetch_field_class(args[:type]).new(**args)
62
+ end
63
+
64
+ private
65
+
66
+ def fetch_field_class(type)
67
+ field_class_name = type.to_s.split("_").map(&:capitalize).join("")
68
+ begin
69
+ const_get("::RailsSettings::Fields::#{field_class_name}")
70
+ rescue StandardError
71
+ ::RailsSettings::Fields::String
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,15 @@
1
+ module RailsSettings
2
+ module Fields
3
+ class BigDecimal < ::RailsSettings::Fields::Base
4
+ def deserialize(value)
5
+ return nil if value.nil?
6
+
7
+ value.to_d
8
+ end
9
+
10
+ def serialize(value)
11
+ deserialize(value)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module RailsSettings
2
+ module Fields
3
+ class Boolean < ::RailsSettings::Fields::Base
4
+ def deserialize(value)
5
+ return nil if value.nil?
6
+
7
+ ["true", "1", 1, true].include?(value)
8
+ end
9
+
10
+ def serialize(value)
11
+ deserialize(value)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module RailsSettings
2
+ module Fields
3
+ class Float < ::RailsSettings::Fields::Base
4
+ def deserialize(value)
5
+ return nil if value.nil?
6
+
7
+ value.to_f
8
+ end
9
+
10
+ def serialize(value)
11
+ deserialize(value)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ module RailsSettings
2
+ module Fields
3
+ class Hash < ::RailsSettings::Fields::Base
4
+ def deserialize(value)
5
+ return nil if value.nil?
6
+
7
+ return value unless value.is_a?(::String)
8
+
9
+ load_value(value).deep_stringify_keys.with_indifferent_access
10
+ end
11
+
12
+ def serialize(value)
13
+ deserialize(value)
14
+ end
15
+
16
+ def load_value(value)
17
+ YAML.safe_load(value).to_h
18
+ rescue StandardError
19
+ {}
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ module RailsSettings
2
+ module Fields
3
+ class Integer < ::RailsSettings::Fields::Base
4
+ def deserialize(value)
5
+ return nil if value.nil?
6
+
7
+ value.to_i
8
+ end
9
+
10
+ def serialize(value)
11
+ deserialize(value)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module RailsSettings
2
+ module Fields
3
+ class String < ::RailsSettings::Fields::Base
4
+ def deserialize(value)
5
+ return nil if value.nil?
6
+
7
+ value
8
+ end
9
+
10
+ def serialize(value)
11
+ deserialize(value)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -3,7 +3,7 @@
3
3
  module RailsSettings
4
4
  class << self
5
5
  def version
6
- "2.8.3"
6
+ "2.9.2"
7
7
  end
8
8
  end
9
9
  end
@@ -1,5 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "rails-settings/fields/base"
4
+ require_relative "rails-settings/fields/array"
5
+ require_relative "rails-settings/fields/big_decimal"
6
+ require_relative "rails-settings/fields/boolean"
7
+ require_relative "rails-settings/fields/float"
8
+ require_relative "rails-settings/fields/hash"
9
+ require_relative "rails-settings/fields/integer"
10
+ require_relative "rails-settings/fields/string"
11
+
3
12
  require_relative "rails-settings/base"
4
13
  require_relative "rails-settings/request_cache"
5
14
  require_relative "rails-settings/middleware"
@@ -7,4 +16,6 @@ require_relative "rails-settings/railtie"
7
16
  require_relative "rails-settings/version"
8
17
 
9
18
  module RailsSettings
19
+ module Fields
20
+ end
10
21
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-settings-cached
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.3
4
+ version: 2.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Lee
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-19 00:00:00.000000000 Z
11
+ date: 2023-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -127,6 +127,14 @@ files:
127
127
  - lib/generators/settings/templates/model.rb
128
128
  - lib/rails-settings-cached.rb
129
129
  - lib/rails-settings/base.rb
130
+ - lib/rails-settings/fields/array.rb
131
+ - lib/rails-settings/fields/base.rb
132
+ - lib/rails-settings/fields/big_decimal.rb
133
+ - lib/rails-settings/fields/boolean.rb
134
+ - lib/rails-settings/fields/float.rb
135
+ - lib/rails-settings/fields/hash.rb
136
+ - lib/rails-settings/fields/integer.rb
137
+ - lib/rails-settings/fields/string.rb
130
138
  - lib/rails-settings/middleware.rb
131
139
  - lib/rails-settings/railtie.rb
132
140
  - lib/rails-settings/request_cache.rb
@@ -150,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
158
  - !ruby/object:Gem::Version
151
159
  version: '0'
152
160
  requirements: []
153
- rubygems_version: 3.3.25
161
+ rubygems_version: 3.4.1
154
162
  signing_key:
155
163
  specification_version: 4
156
164
  summary: The best solution for store global settings in Rails applications.