Skip to content

Commit

Permalink
Reformat with Prettier
Browse files Browse the repository at this point in the history
  • Loading branch information
ledermann committed Sep 22, 2023
1 parent 868ce11 commit e6f9c33
Show file tree
Hide file tree
Showing 19 changed files with 371 additions and 278 deletions.
10 changes: 3 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ Ruby gem to handle settings for ActiveRecord instances by storing them as serial

## Requirements

* Ruby 3.0 or newer
* Rails 6.1 or newer (including Rails 7.0)

- Ruby 3.0 or newer
- Rails 6.1 or newer (including Rails 7.0)

## Installation

Expand All @@ -27,7 +26,6 @@ rails g rails_settings:migration
rake db:migrate
```


## Usage

### Define settings
Expand Down Expand Up @@ -103,7 +101,6 @@ user.settings(:dashboard).update! :theme => 'black'
user.settings(:calendar).update! :scope => 'all', :display => 'daily'
```


### Get settings

```ruby
Expand Down Expand Up @@ -145,6 +142,7 @@ User.without_settings_for(:calendar)
```

### Eager Loading

```ruby
User.includes(:setting_objects)
# => Eager load setting_objects when querying many users
Expand All @@ -156,12 +154,10 @@ Version 2 is a complete rewrite and has a new DSL, so it's **not** compatible wi

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.


## Changelog

See https://github.com/ledermann/rails-settings/releases


## License

MIT License
Expand Down
2 changes: 1 addition & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec)

task :default => :spec
task default: :spec
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@ module RailsSettings
class MigrationGenerator < Rails::Generators::Base
include Rails::Generators::Migration

desc "Generates migration for rails-settings"
desc 'Generates migration for rails-settings'
source_root File.expand_path('../templates', __FILE__)

def create_migration_file
migration_template 'migration.rb', 'db/migrate/rails_settings_migration.rb'
migration_template 'migration.rb',
'db/migrate/rails_settings_migration.rb'
end

def self.next_migration_number(dirname)
if ActiveRecord::Base.timestamped_migrations
Time.now.utc.strftime("%Y%m%d%H%M%S")
Time.now.utc.strftime('%Y%m%d%H%M%S')
else
"%.3d" % (current_migration_number(dirname) + 1)
'%.3d' % (current_migration_number(dirname) + 1)
end
end
end
Expand Down
10 changes: 5 additions & 5 deletions lib/generators/rails_settings/migration/templates/migration.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
class RailsSettingsMigration < ActiveRecord::Migration[5.0]
def self.up
create_table :settings do |t|
t.string :var, :null => false
t.text :value
t.references :target, :null => false, :polymorphic => true
t.timestamps :null => true
t.string :var, null: false
t.text :value
t.references :target, null: false, polymorphic: true
t.timestamps null: true
end
add_index :settings, [ :target_type, :target_id, :var ], :unique => true
add_index :settings, %i[target_type target_id var], unique: true
end

def self.down
Expand Down
29 changes: 19 additions & 10 deletions lib/rails-settings/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,23 @@ module Base
def self.included(base)
base.class_eval do
has_many :setting_objects,
:as => :target,
:autosave => true,
:dependent => :delete_all,
:class_name => self.setting_object_class_name
as: :target,
autosave: true,
dependent: :delete_all,
class_name: self.setting_object_class_name

def settings(var)
raise ArgumentError unless var.is_a?(Symbol)
raise ArgumentError.new("Unknown key: #{var}") unless self.class.default_settings[var]
unless self.class.default_settings[var]
raise ArgumentError.new("Unknown key: #{var}")
end

if RailsSettings.can_protect_attributes?
setting_objects.detect { |s| s.var == var.to_s } || setting_objects.build({ :var => var.to_s }, :without_protection => true)
setting_objects.detect { |s| s.var == var.to_s } ||
setting_objects.build({ var: var.to_s }, without_protection: true)
else
setting_objects.detect { |s| s.var == var.to_s } || setting_objects.build(:var => var.to_s, :target => self)
setting_objects.detect { |s| s.var == var.to_s } ||
setting_objects.build(var: var.to_s, target: self)
end
end

Expand All @@ -27,9 +31,12 @@ def settings=(value)
end
end

def settings?(var=nil)
def settings?(var = nil)
if var.nil?
setting_objects.any? { |setting_object| !setting_object.marked_for_destruction? && setting_object.value.present? }
setting_objects.any? do |setting_object|
!setting_object.marked_for_destruction? &&
setting_object.value.present?
end
else
settings(var).value.present?
end
Expand All @@ -38,7 +45,9 @@ def settings?(var=nil)
def to_settings_hash
settings_hash = self.class.default_settings.dup
settings_hash.each do |var, vals|
settings_hash[var] = settings_hash[var].merge(settings(var.to_sym).value)
settings_hash[var] = settings_hash[var].merge(
settings(var.to_sym).value,
)
end
settings_hash
end
Expand Down
33 changes: 23 additions & 10 deletions lib/rails-settings/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,43 @@ def initialize(*args, &block)
@klass = klass

if options[:persistent]
@klass.class_attribute :default_settings unless @klass.methods.include?(:default_settings)
unless @klass.methods.include?(:default_settings)
@klass.class_attribute :default_settings
end
else
@klass.class_attribute :default_settings
end

@klass.class_attribute :setting_object_class_name
@klass.default_settings ||= {}
@klass.setting_object_class_name = options[:class_name] || 'RailsSettings::SettingObject'
@klass.setting_object_class_name =
options[:class_name] || 'RailsSettings::SettingObject'

if block_given?
yield(self)
else
keys.each do |k|
key(k)
end
keys.each { |k| key(k) }
end

raise ArgumentError.new('has_settings: No keys defined') if @klass.default_settings.blank?
if @klass.default_settings.blank?
raise ArgumentError.new('has_settings: No keys defined')
end
end

def key(name, options={})
raise ArgumentError.new("has_settings: Symbol expected, but got a #{name.class}") unless name.is_a?(Symbol)
raise ArgumentError.new("has_settings: Option :defaults expected, but got #{options.keys.join(', ')}") unless options.blank? || (options.keys == [:defaults])
@klass.default_settings[name] = (options[:defaults] || {}).stringify_keys.freeze
def key(name, options = {})
unless name.is_a?(Symbol)
raise ArgumentError.new(
"has_settings: Symbol expected, but got a #{name.class}",
)
end
unless options.blank? || (options.keys == [:defaults])
raise ArgumentError.new(
"has_settings: Option :defaults expected, but got #{options.keys.join(', ')}",
)
end
@klass.default_settings[name] = (
options[:defaults] || {}
).stringify_keys.freeze
end
end
end
14 changes: 9 additions & 5 deletions lib/rails-settings/scopes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,22 @@ def with_settings

def with_settings_for(var)
raise ArgumentError.new('Symbol expected!') unless var.is_a?(Symbol)
joins("INNER JOIN settings ON #{settings_join_condition} AND settings.var = '#{var}'")
joins(
"INNER JOIN settings ON #{settings_join_condition} AND settings.var = '#{var}'",
)
end

def without_settings
joins("LEFT JOIN settings ON #{settings_join_condition}").
where('settings.id IS NULL')
joins("LEFT JOIN settings ON #{settings_join_condition}").where(
'settings.id IS NULL',
)
end

def without_settings_for(var)
raise ArgumentError.new('Symbol expected!') unless var.is_a?(Symbol)
joins("LEFT JOIN settings ON #{settings_join_condition} AND settings.var = '#{var}'").
where('settings.id IS NULL')
joins(
"LEFT JOIN settings ON #{settings_join_condition} AND settings.var = '#{var}'",
).where('settings.id IS NULL')
end

def settings_join_condition
Expand Down
32 changes: 21 additions & 11 deletions lib/rails-settings/setting_object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ module RailsSettings
class SettingObject < ActiveRecord::Base
self.table_name = 'settings'

belongs_to :target, :polymorphic => true
belongs_to :target, polymorphic: true

validates_presence_of :var, :target_type
validate do
errors.add(:value, "Invalid setting value") unless value.is_a? Hash
errors.add(:value, 'Invalid setting value') unless value.is_a? Hash

unless _target_class.default_settings[var.to_sym]
errors.add(:var, "#{var} is not defined!")
end
end

if ActiveRecord.version >= Gem::Version.new("7.1.0.beta1")
if ActiveRecord.version >= Gem::Version.new('7.1.0.beta1')
serialize :value, type: Hash
else
serialize :value, Hash
Expand All @@ -28,15 +28,15 @@ class SettingObject < ActiveRecord::Base
REGEX_SETTER = /\A([a-z]\w*)=\Z/i
REGEX_GETTER = /\A([a-z]\w*)\Z/i

def respond_to?(method_name, include_priv=false)
def respond_to?(method_name, include_priv = false)
super || method_name.to_s =~ REGEX_SETTER || _setting?(method_name)
end

def method_missing(method_name, *args, &block)
if block_given?
super
else
if attribute_names.include?(method_name.to_s.sub('=',''))
if attribute_names.include?(method_name.to_s.sub('=', ''))
super
elsif method_name.to_s =~ REGEX_SETTER && args.size == 1
_set_value($1, args.first)
Expand All @@ -48,15 +48,25 @@ def method_missing(method_name, *args, &block)
end
end

protected
protected

if RailsSettings.can_protect_attributes?
# Simulate attr_protected by removing all regular attributes
def sanitize_for_mass_assignment(attributes, role = nil)
attributes.except('id', 'var', 'value', 'target_id', 'target_type', 'created_at', 'updated_at')
attributes.except(
'id',
'var',
'value',
'target_id',
'target_type',
'created_at',
'updated_at',
)
end
end

private
private

def _get_value(name)
if value[name].nil?
default_value = _get_default_value(name)
Expand All @@ -65,17 +75,17 @@ def _get_value(name)
value[name]
end
end

def _get_default_value(name)
default_value = _target_class.default_settings[var.to_sym][name]

if default_value.respond_to?(:call)
default_value.call(target)
else
default_value
end
end

def _deep_dup(nested_hashes_and_or_arrays)
Marshal.load(Marshal.dump(nested_hashes_and_or_arrays))
end
Expand Down
23 changes: 12 additions & 11 deletions rails-settings.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'rails-settings/version'

Gem::Specification.new do |gem|
gem.name = 'ledermann-rails-settings'
gem.version = RailsSettings::VERSION
gem.licenses = ['MIT']
gem.authors = ['Georg Ledermann']
gem.email = ['georg@ledermann.dev']
gem.description = %q{Settings gem for Ruby on Rails}
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.}
gem.homepage = 'https://github.com/ledermann/rails-settings'
gem.name = 'ledermann-rails-settings'
gem.version = RailsSettings::VERSION
gem.licenses = ['MIT']
gem.authors = ['Georg Ledermann']
gem.email = ['georg@ledermann.dev']
gem.description = 'Settings gem for Ruby on Rails'
gem.summary =
'Ruby gem to handle settings for ActiveRecord instances by storing them as serialized Hash in a separate database table. Namespaces and defaults included.'
gem.homepage = 'https://github.com/ledermann/rails-settings'
gem.required_ruby_version = '>= 3.0'

gem.files = `git ls-files`.split($/)
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
gem.files = `git ls-files`.split($/)
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
gem.require_paths = ['lib']

gem.add_dependency 'activerecord', '>= 6.1'
Expand Down
Loading

0 comments on commit e6f9c33

Please sign in to comment.