ledermann-rails-settings 2.5.0 → 2.6.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d35191c6b15823ec6934c9b66a8cf4291aa552c79bfe1ac6e24b2298a3bf6942
4
- data.tar.gz: 1dabb6089d5894acc9f16aa57637daded9e9751c590b924fe3a8d3e074e01ac8
3
+ metadata.gz: 0cdc4dfa32d7d13c88e8a15d05cf3d6e12de8fae5b4ce519220c4842b13a05f3
4
+ data.tar.gz: 630ca38fb7dd52414d95ffabbd760f214a5388bf0bd4c9ecaebf8d9d8bc271d5
5
5
  SHA512:
6
- metadata.gz: 2556adc7367efd4acd8a208d342d4f485ea356a79b1bac8971785bb2d3ab9ea3d31ec13b2008fe4e58171eb181090e7d7b18f3a242ee220fee9703777c7ca387
7
- data.tar.gz: b391a6f0c86c8abab56b8b68b20161fbe4981c7d08acfa5766416d097d0c2ada7c77db29182b46b62853f0e822b77cc21ae300b3f42657c50cdebc7d83bdf4a8
6
+ metadata.gz: fe775476b9833dfef63d5f6238492a4f5444524c2202aa6c6714db029044c99f429d16e91f14a38bf6880be776ffc047d93bfc9f0fd688def68bdf17b331f2a3
7
+ data.tar.gz: 785198cb40150cd606726b979df0ecdb2933a59c833adbe2d0237af6d66b821029762f0de3d7e7922733e2a26eb690ca62ca6878bf2bd1aa8520a09e1966e30b
@@ -0,0 +1,39 @@
1
+ name: Test
2
+
3
+ on:
4
+ - push
5
+ - pull_request
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ ruby_version:
15
+ - '3.0'
16
+ - '3.1'
17
+ - '3.2'
18
+ gemfile:
19
+ - gemfiles/rails_6_1.gemfile
20
+ - gemfiles/rails_7_0.gemfile
21
+ - gemfiles/rails_7_1.gemfile
22
+
23
+ name: Ruby ${{ matrix.ruby_version }} / Gemfile ${{ matrix.gemfile }}
24
+
25
+ env:
26
+ BUNDLE_GEMFILE: ${{ matrix.gemfile }}
27
+ COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
28
+
29
+ steps:
30
+ - uses: actions/checkout@v4
31
+
32
+ - name: Setup Ruby
33
+ uses: ruby/setup-ruby@v1
34
+ with:
35
+ ruby-version: ${{ matrix.ruby_version }}
36
+ bundler-cache: true
37
+
38
+ - name: RSpec
39
+ run: bundle exec rake
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012-2019 Georg Ledermann
1
+ Copyright (c) 2012-2023 Georg Ledermann
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Settings for Rails
2
2
 
3
- [![Build Status](https://travis-ci.org/ledermann/rails-settings.svg?branch=master)](https://travis-ci.org/ledermann/rails-settings)
3
+ [![Build Status](https://github.com/ledermann/rails-settings/actions/workflows/main.yml/badge.svg)](https://github.com/ledermann/rails-settings/actions)
4
4
  [![Code Climate](https://codeclimate.com/github/ledermann/rails-settings.svg)](https://codeclimate.com/github/ledermann/rails-settings)
5
5
  [![Coverage Status](https://coveralls.io/repos/ledermann/rails-settings/badge.svg?branch=master)](https://coveralls.io/r/ledermann/rails-settings?branch=master)
6
6
 
@@ -8,9 +8,8 @@ Ruby gem to handle settings for ActiveRecord instances by storing them as serial
8
8
 
9
9
  ## Requirements
10
10
 
11
- * Ruby 2.4 or newer
12
- * Rails 4.2 or newer (including Rails 6)
13
-
11
+ - Ruby 3.0 or newer
12
+ - Rails 6.1 or newer (including Rails 7.0)
14
13
 
15
14
  ## Installation
16
15
 
@@ -27,7 +26,6 @@ rails g rails_settings:migration
27
26
  rake db:migrate
28
27
  ```
29
28
 
30
-
31
29
  ## Usage
32
30
 
33
31
  ### Define settings
@@ -103,7 +101,6 @@ user.settings(:dashboard).update! :theme => 'black'
103
101
  user.settings(:calendar).update! :scope => 'all', :display => 'daily'
104
102
  ```
105
103
 
106
-
107
104
  ### Get settings
108
105
 
109
106
  ```ruby
@@ -145,6 +142,7 @@ User.without_settings_for(:calendar)
145
142
  ```
146
143
 
147
144
  ### Eager Loading
145
+
148
146
  ```ruby
149
147
  User.includes(:setting_objects)
150
148
  # => Eager load setting_objects when querying many users
@@ -156,16 +154,14 @@ Version 2 is a complete rewrite and has a new DSL, so it's **not** compatible wi
156
154
 
157
155
  If you don't want to upgrade, you find the old version in the [1.x](https://github.com/ledermann/rails-settings/commits/1.x) branch. But don't expect any updates there.
158
156
 
159
-
160
157
  ## Changelog
161
158
 
162
159
  See https://github.com/ledermann/rails-settings/releases
163
160
 
164
-
165
161
  ## License
166
162
 
167
163
  MIT License
168
164
 
169
- Copyright (c) 2012-2019 [Georg Ledermann](http://www.georg-ledermann.de)
165
+ Copyright (c) 2012-2023 [Georg Ledermann](https://ledermann.dev)
170
166
 
171
167
  This gem is a complete rewrite of [rails-settings](https://github.com/Squeegy/rails-settings) by [Alex Wayne](https://github.com/Squeegy)
data/Rakefile CHANGED
@@ -3,4 +3,4 @@ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
6
+ task default: :spec
@@ -1,6 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'activerecord', '~> 6.0.0'
3
+ gem 'activerecord', '~> 6.1.2'
4
4
  gem "sqlite3", "~> 1.4"
5
5
 
6
6
  gemspec :path => "../"
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 7.0.0'
4
+ gem "sqlite3", "~> 1.4"
5
+
6
+ gemspec :path => "../"
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 7.1.0'
4
+ gem "sqlite3", "~> 1.4"
5
+
6
+ gemspec :path => "../"
@@ -5,19 +5,25 @@ module RailsSettings
5
5
  class MigrationGenerator < Rails::Generators::Base
6
6
  include Rails::Generators::Migration
7
7
 
8
- desc "Generates migration for rails-settings"
8
+ desc 'Generates migration for rails-settings'
9
9
  source_root File.expand_path('../templates', __FILE__)
10
10
 
11
11
  def create_migration_file
12
- migration_template 'migration.rb', 'db/migrate/rails_settings_migration.rb'
12
+ migration_template 'migration.rb',
13
+ 'db/migrate/rails_settings_migration.rb'
13
14
  end
14
15
 
15
16
  def self.next_migration_number(dirname)
16
- if ActiveRecord::Base.timestamped_migrations
17
- Time.now.utc.strftime("%Y%m%d%H%M%S")
17
+ if timestamped_migrations?
18
+ Time.now.utc.strftime('%Y%m%d%H%M%S')
18
19
  else
19
- "%.3d" % (current_migration_number(dirname) + 1)
20
+ '%.3d' % (current_migration_number(dirname) + 1)
20
21
  end
21
22
  end
23
+
24
+ def self.timestamped_migrations?
25
+ (ActiveRecord::Base.respond_to?(:timestamped_migrations) && ActiveRecord::Base.timestamped_migrations) ||
26
+ (ActiveRecord.respond_to?(:timestamped_migrations) && ActiveRecord.timestamped_migrations)
27
+ end
22
28
  end
23
29
  end
@@ -1,18 +1,12 @@
1
- MIGRATION_BASE_CLASS = if ActiveRecord::VERSION::MAJOR >= 5
2
- ActiveRecord::Migration[5.0]
3
- else
4
- ActiveRecord::Migration
5
- end
6
-
7
- class RailsSettingsMigration < MIGRATION_BASE_CLASS
1
+ class RailsSettingsMigration < ActiveRecord::Migration[5.0]
8
2
  def self.up
9
3
  create_table :settings do |t|
10
- t.string :var, :null => false
11
- t.text :value
12
- t.references :target, :null => false, :polymorphic => true
13
- t.timestamps :null => true
4
+ t.string :var, null: false
5
+ t.text :value
6
+ t.references :target, null: false, polymorphic: true
7
+ t.timestamps null: true
14
8
  end
15
- add_index :settings, [ :target_type, :target_id, :var ], :unique => true
9
+ add_index :settings, %i[target_type target_id var], unique: true
16
10
  end
17
11
 
18
12
  def self.down
@@ -3,19 +3,23 @@ module RailsSettings
3
3
  def self.included(base)
4
4
  base.class_eval do
5
5
  has_many :setting_objects,
6
- :as => :target,
7
- :autosave => true,
8
- :dependent => :delete_all,
9
- :class_name => self.setting_object_class_name
6
+ as: :target,
7
+ autosave: true,
8
+ dependent: :delete_all,
9
+ class_name: self.setting_object_class_name
10
10
 
11
11
  def settings(var)
12
12
  raise ArgumentError unless var.is_a?(Symbol)
13
- raise ArgumentError.new("Unknown key: #{var}") unless self.class.default_settings[var]
13
+ unless self.class.default_settings[var]
14
+ raise ArgumentError.new("Unknown key: #{var}")
15
+ end
14
16
 
15
17
  if RailsSettings.can_protect_attributes?
16
- setting_objects.detect { |s| s.var == var.to_s } || setting_objects.build({ :var => var.to_s }, :without_protection => true)
18
+ setting_objects.detect { |s| s.var == var.to_s } ||
19
+ setting_objects.build({ var: var.to_s }, without_protection: true)
17
20
  else
18
- setting_objects.detect { |s| s.var == var.to_s } || setting_objects.build(:var => var.to_s, :target => self)
21
+ setting_objects.detect { |s| s.var == var.to_s } ||
22
+ setting_objects.build(var: var.to_s, target: self)
19
23
  end
20
24
  end
21
25
 
@@ -27,9 +31,12 @@ module RailsSettings
27
31
  end
28
32
  end
29
33
 
30
- def settings?(var=nil)
34
+ def settings?(var = nil)
31
35
  if var.nil?
32
- setting_objects.any? { |setting_object| !setting_object.marked_for_destruction? && setting_object.value.present? }
36
+ setting_objects.any? do |setting_object|
37
+ !setting_object.marked_for_destruction? &&
38
+ setting_object.value.present?
39
+ end
33
40
  else
34
41
  settings(var).value.present?
35
42
  end
@@ -38,7 +45,9 @@ module RailsSettings
38
45
  def to_settings_hash
39
46
  settings_hash = self.class.default_settings.dup
40
47
  settings_hash.each do |var, vals|
41
- settings_hash[var] = settings_hash[var].merge(settings(var.to_sym).value)
48
+ settings_hash[var] = settings_hash[var].merge(
49
+ settings(var.to_sym).value,
50
+ )
42
51
  end
43
52
  settings_hash
44
53
  end
@@ -10,30 +10,43 @@ module RailsSettings
10
10
  @klass = klass
11
11
 
12
12
  if options[:persistent]
13
- @klass.class_attribute :default_settings unless @klass.methods.include?(:default_settings)
13
+ unless @klass.methods.include?(:default_settings)
14
+ @klass.class_attribute :default_settings
15
+ end
14
16
  else
15
17
  @klass.class_attribute :default_settings
16
18
  end
17
19
 
18
20
  @klass.class_attribute :setting_object_class_name
19
21
  @klass.default_settings ||= {}
20
- @klass.setting_object_class_name = options[:class_name] || 'RailsSettings::SettingObject'
22
+ @klass.setting_object_class_name =
23
+ options[:class_name] || 'RailsSettings::SettingObject'
21
24
 
22
25
  if block_given?
23
26
  yield(self)
24
27
  else
25
- keys.each do |k|
26
- key(k)
27
- end
28
+ keys.each { |k| key(k) }
28
29
  end
29
30
 
30
- raise ArgumentError.new('has_settings: No keys defined') if @klass.default_settings.blank?
31
+ if @klass.default_settings.blank?
32
+ raise ArgumentError.new('has_settings: No keys defined')
33
+ end
31
34
  end
32
35
 
33
- def key(name, options={})
34
- raise ArgumentError.new("has_settings: Symbol expected, but got a #{name.class}") unless name.is_a?(Symbol)
35
- raise ArgumentError.new("has_settings: Option :defaults expected, but got #{options.keys.join(', ')}") unless options.blank? || (options.keys == [:defaults])
36
- @klass.default_settings[name] = (options[:defaults] || {}).stringify_keys.freeze
36
+ def key(name, options = {})
37
+ unless name.is_a?(Symbol)
38
+ raise ArgumentError.new(
39
+ "has_settings: Symbol expected, but got a #{name.class}",
40
+ )
41
+ end
42
+ unless options.blank? || (options.keys == [:defaults])
43
+ raise ArgumentError.new(
44
+ "has_settings: Option :defaults expected, but got #{options.keys.join(', ')}",
45
+ )
46
+ end
47
+ @klass.default_settings[name] = (
48
+ options[:defaults] || {}
49
+ ).stringify_keys.freeze
37
50
  end
38
51
  end
39
52
  end
@@ -2,28 +2,27 @@ module RailsSettings
2
2
  module Scopes
3
3
  def with_settings
4
4
  result = joins("INNER JOIN settings ON #{settings_join_condition}")
5
-
6
- if ActiveRecord::VERSION::MAJOR < 5
7
- result.uniq
8
- else
9
- result.distinct
10
- end
5
+ result.distinct
11
6
  end
12
7
 
13
8
  def with_settings_for(var)
14
9
  raise ArgumentError.new('Symbol expected!') unless var.is_a?(Symbol)
15
- joins("INNER JOIN settings ON #{settings_join_condition} AND settings.var = '#{var}'")
10
+ joins(
11
+ "INNER JOIN settings ON #{settings_join_condition} AND settings.var = '#{var}'",
12
+ )
16
13
  end
17
14
 
18
15
  def without_settings
19
- joins("LEFT JOIN settings ON #{settings_join_condition}").
20
- where('settings.id IS NULL')
16
+ joins("LEFT JOIN settings ON #{settings_join_condition}").where(
17
+ 'settings.id IS NULL',
18
+ )
21
19
  end
22
20
 
23
21
  def without_settings_for(var)
24
22
  raise ArgumentError.new('Symbol expected!') unless var.is_a?(Symbol)
25
- joins("LEFT JOIN settings ON #{settings_join_condition} AND settings.var = '#{var}'").
26
- where('settings.id IS NULL')
23
+ joins(
24
+ "LEFT JOIN settings ON #{settings_join_condition} AND settings.var = '#{var}'",
25
+ ).where('settings.id IS NULL')
27
26
  end
28
27
 
29
28
  def settings_join_condition
@@ -2,18 +2,22 @@ module RailsSettings
2
2
  class SettingObject < ActiveRecord::Base
3
3
  self.table_name = 'settings'
4
4
 
5
- belongs_to :target, :polymorphic => true
5
+ belongs_to :target, polymorphic: true
6
6
 
7
7
  validates_presence_of :var, :target_type
8
8
  validate do
9
- errors.add(:value, "Invalid setting value") unless value.is_a? Hash
9
+ errors.add(:value, 'Invalid setting value') unless value.is_a? Hash
10
10
 
11
11
  unless _target_class.default_settings[var.to_sym]
12
12
  errors.add(:var, "#{var} is not defined!")
13
13
  end
14
14
  end
15
15
 
16
- serialize :value, Hash
16
+ if ActiveRecord.version >= Gem::Version.new('7.1.0.beta1')
17
+ serialize :value, type: Hash
18
+ else
19
+ serialize :value, Hash
20
+ end
17
21
 
18
22
  if RailsSettings.can_protect_attributes?
19
23
  # attr_protected can not be used here because it touches the database which is not connected yet.
@@ -21,10 +25,10 @@ module RailsSettings
21
25
  attr_accessible
22
26
  end
23
27
 
24
- REGEX_SETTER = /\A([a-z]\w+)=\Z/i
25
- REGEX_GETTER = /\A([a-z]\w+)\Z/i
28
+ REGEX_SETTER = /\A([a-z]\w*)=\Z/i
29
+ REGEX_GETTER = /\A([a-z]\w*)\Z/i
26
30
 
27
- def respond_to?(method_name, include_priv=false)
31
+ def respond_to?(method_name, include_priv = false)
28
32
  super || method_name.to_s =~ REGEX_SETTER || _setting?(method_name)
29
33
  end
30
34
 
@@ -32,7 +36,7 @@ module RailsSettings
32
36
  if block_given?
33
37
  super
34
38
  else
35
- if attribute_names.include?(method_name.to_s.sub('=',''))
39
+ if attribute_names.include?(method_name.to_s.sub('=', ''))
36
40
  super
37
41
  elsif method_name.to_s =~ REGEX_SETTER && args.size == 1
38
42
  _set_value($1, args.first)
@@ -44,23 +48,48 @@ module RailsSettings
44
48
  end
45
49
  end
46
50
 
47
- protected
51
+ protected
52
+
48
53
  if RailsSettings.can_protect_attributes?
49
54
  # Simulate attr_protected by removing all regular attributes
50
55
  def sanitize_for_mass_assignment(attributes, role = nil)
51
- attributes.except('id', 'var', 'value', 'target_id', 'target_type', 'created_at', 'updated_at')
56
+ attributes.except(
57
+ 'id',
58
+ 'var',
59
+ 'value',
60
+ 'target_id',
61
+ 'target_type',
62
+ 'created_at',
63
+ 'updated_at',
64
+ )
52
65
  end
53
66
  end
54
67
 
55
- private
68
+ private
69
+
56
70
  def _get_value(name)
57
71
  if value[name].nil?
58
- _target_class.default_settings[var.to_sym][name]
72
+ default_value = _get_default_value(name)
73
+ _deep_dup(default_value)
59
74
  else
60
75
  value[name]
61
76
  end
62
77
  end
63
78
 
79
+ def _get_default_value(name)
80
+ default_value = _target_class.default_settings[var.to_sym][name]
81
+
82
+ if default_value.respond_to?(:call)
83
+ default_value.call(target)
84
+ else
85
+ default_value
86
+ end
87
+ end
88
+
89
+ def _deep_dup(nested_hashes_and_or_arrays)
90
+ Marshal.load(Marshal.dump(nested_hashes_and_or_arrays))
91
+ end
92
+
64
93
  def _set_value(name, v)
65
94
  if value[name] != v
66
95
  value_will_change!
@@ -1,3 +1,3 @@
1
1
  module RailsSettings
2
- VERSION = '2.5.0'
2
+ VERSION = '2.6.1'
3
3
  end
@@ -4,26 +4,27 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'rails-settings/version'
5
5
 
6
6
  Gem::Specification.new do |gem|
7
- gem.name = 'ledermann-rails-settings'
8
- gem.version = RailsSettings::VERSION
9
- gem.licenses = ['MIT']
10
- gem.authors = ['Georg Ledermann']
11
- gem.email = ['mail@georg-ledermann.de']
12
- gem.description = %q{Settings gem for Ruby on Rails}
13
- gem.summary = %q{Ruby gem to handle settings for ActiveRecord instances by storing them as serialized Hash in a separate database table. Namespaces and defaults included.}
14
- gem.homepage = 'https://github.com/ledermann/rails-settings'
15
- gem.required_ruby_version = '>= 2.4'
7
+ gem.name = 'ledermann-rails-settings'
8
+ gem.version = RailsSettings::VERSION
9
+ gem.licenses = ['MIT']
10
+ gem.authors = ['Georg Ledermann']
11
+ gem.email = ['georg@ledermann.dev']
12
+ gem.description = 'Settings gem for Ruby on Rails'
13
+ gem.summary =
14
+ 'Ruby gem to handle settings for ActiveRecord instances by storing them as serialized Hash in a separate database table. Namespaces and defaults included.'
15
+ gem.homepage = 'https://github.com/ledermann/rails-settings'
16
+ gem.required_ruby_version = '>= 3.0'
16
17
 
17
- gem.files = `git ls-files`.split($/)
18
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
19
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.files = `git ls-files`.split($/)
19
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
20
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
20
21
  gem.require_paths = ['lib']
21
22
 
22
- gem.add_dependency 'activerecord', '>= 4.2'
23
+ gem.add_dependency 'activerecord', '>= 6.1'
23
24
 
24
25
  gem.add_development_dependency 'rake'
25
26
  gem.add_development_dependency 'sqlite3'
26
27
  gem.add_development_dependency 'rspec'
27
- gem.add_development_dependency 'coveralls'
28
+ gem.add_development_dependency 'coveralls_reborn'
28
29
  gem.add_development_dependency 'simplecov', '>= 0.11.2'
29
30
  end