Skip to content

Commit ac490eb

Browse files
committed
remove dry-rb + compatible with new ruby/rails
1 parent d25cbdb commit ac490eb

35 files changed

+527
-346
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ spec/dummy/db/*.sqlite3
1010
spec/dummy/log/*.log
1111
spec/dummy/tmp/
1212
coverage/
13+
.ruby-version

CHANGES.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
* YOUR CONTRIBUTIONS HERE
44

5+
## v2.0.0
6+
7+
* removing dry-rb
8+
* add rails-settings-cached as dependency
9+
* add support for ruby 3.1 and new Rails
10+
511
## v1.3.5
612
* use dry-validation < 1.0
713

Gemfile

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
source "http://rubygems.org"
1+
source 'http://rubygems.org'
22

33
gemspec
44

55
group :development, :test do
6-
gem "sqlite3"
7-
gem "rails-settings-cached", '0.5.4'
6+
gem 'pry'
7+
gem 'sqlite3'
8+
gem 'rails-settings-cached', '2.8.2'
89
end

README.md

Lines changed: 13 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,20 @@ Rails settings UI
66
[![Code Climate](https://codeclimate.com/github/accessd/rails-settings-ui/badges/gpa.svg)](https://codeclimate.com/github/accessd/rails-settings-ui)
77
[![Test Coverage](https://codeclimate.com/github/accessd/rails-settings-ui/badges/coverage.svg)](https://codeclimate.com/github/accessd/rails-settings-ui/coverage)
88

9-
A Rails Engine to manage your application settings. Includes validation. Compatible with Rails 5.
10-
It compatible with [rails-settings-cached](https://github.com/huacnlee/rails-settings-cached) gem.
9+
A Rails Engine to manage your application settings. Includes validation. Compatible with Rails 7.
10+
It depends on [rails-settings-cached](https://github.com/huacnlee/rails-settings-cached) gem.
1111

1212
Preview:
1313

1414
![ScreenShot](https://raw.github.com/accessd/rails-settings-ui/master/doc/img/settings-page.png)
1515

16-
Live example: http://rails-settings-ui.herokuapp.com/
17-
1816
How to
1917
-----
2018

2119
Add to Gemfile
2220

2321
gem 'rails-settings-ui'
2422

25-
then add
26-
27-
gem 'rails-settings-cached'
28-
29-
or
30-
31-
gem 'rails-settings'
32-
33-
or your fork of rails-settings.
34-
3523
If you want to use bootstrap interface you need also include bootstrap stylesheets to your app.
3624
You may use [bootstrap-sass](https://github.com/twbs/bootstrap-sass) gem for that.
3725

@@ -115,55 +103,24 @@ if you don't specify labels in locale config, you'll get:
115103
settings:
116104
attributes:
117105
launch_mode:
118-
help_block: 'Rocket launch mode'
106+
help_block: 'launch mode'
119107
```
120108
121109
Validations
122110
-------------
123111
124-
To validation work is required the default settings in the proper format, eg:
112+
Validations work based on default value for setting or by explicitly specify type for setting, eg:
125113
126-
For rails-settings-cached up to 0.5.8:
114+
class Settings < RailsSettings::Base
115+
cache_prefix { "v1" }
127116
128-
class Settings < RailsSettings::CachedSettings
129-
defaults[:company_name] = "Company name"
130-
defaults[:head_name] = "Head name"
131-
defaults[:manager_premium] = 19
132-
defaults[:show_contract_fields] = true
133-
defaults[:launch_mode] = [:auto, :manual]
117+
field :company_name, type: :string, default: "Company name"
118+
field :head_name, default: "Head name"
119+
field :manager_premium, default: 19
120+
field :show_contract_fields, default: true
121+
field :launch_mode, default: [:auto, :manual]
134122
end
135123
136-
For rails-settings-cached with version >= 0.6.0 default settings moved to YAML config file (config/app.yml), so
137-
defaults should looks like:
138-
139-
```yaml
140-
defaults: &defaults
141-
rocket_name: "Foo"
142-
limit: 123
143-
launch_mode:
144-
- auto
145-
- manual
146-
spaceports:
147-
- plesetsk
148-
- baikonur
149-
style:
150-
border_color: 'e0e0e0'
151-
block_color: 'ffffff'
152-
title:
153-
font: "Tahoma"
154-
size: "12"
155-
color: '107821'
156-
157-
development:
158-
<<: *defaults
159-
160-
test:
161-
<<: *defaults
162-
163-
production:
164-
<<: *defaults
165-
```
166-
167124
Views
168125
-------------
169126
@@ -192,10 +149,10 @@ Alternatively, to have custom rules just for rails-setting-ui you can:
192149

193150
Rails.application.config.to_prepare do
194151
RailsSettingsUi::ApplicationController.module_eval do
195-
before_filter :check_settings_permissions # for Rails 3
196-
before_action :check_settings_permissions # starting from Rails 4
152+
before_action :check_settings_permissions
197153

198154
private
155+
199156
def check_settings_permissions
200157
render status: 403 unless current_user && can_manage_settings?(current_user)
201158
end

app/controllers/rails_settings_ui/settings_controller.rb

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
class RailsSettingsUi::SettingsController < RailsSettingsUi::ApplicationController
22
include RailsSettingsUi::SettingsHelper
33
before_action :collection
4-
before_action :validate_settings, only: :update_all
4+
before_action :cast_settings_params, only: :update_all
55

66
def index
77
end
88

99
def update_all
10-
if @errors.any?
10+
if @casted_settings[:errors].any?
11+
@errors = @casted_settings[:errors]
1112
render :index
1213
else
13-
coerced_values.each { |name, value| RailsSettingsUi.settings_klass[name] = value }
14+
@casted_settings.map do |name, value|
15+
next if name == 'errors'
16+
17+
sc = RailsSettingsUi.setting_config(name)
18+
next if sc[:readonly] == true
19+
20+
RailsSettingsUi.settings_klass.public_send("#{name}=", value)
21+
end
1422
flash[:success] = t('settings.index.settings_saved')
1523
redirect_to [:settings]
1624
end
@@ -19,23 +27,19 @@ def update_all
1927
private
2028

2129
def collection
22-
all_settings_without_ignored = all_settings.reject{ |name, _description| RailsSettingsUi.ignored_settings.include?(name.to_sym) }
30+
all_settings_without_ignored = all_settings.reject do |name, _description|
31+
RailsSettingsUi.ignored_settings.include?(name.to_sym)
32+
end
2333
@settings = Hash[all_settings_without_ignored]
2434
@errors = {}
2535
end
2636

27-
def validate_settings
28-
# validation schema accepts hash (http://dry-rb.org/gems/dry-validation/forms/) so we're converting
29-
# ActionController::Parameters => ActiveSupport::HashWithIndifferentAccess
30-
@errors = RailsSettingsUi::SettingsFormValidator.new(default_settings, settings_from_params).errors
31-
end
32-
33-
def coerced_values
34-
RailsSettingsUi::SettingsFormCoercible.new(default_settings, settings_from_params).coerce!
37+
def cast_settings_params
38+
@casted_settings = RailsSettingsUi::TypeConverter.cast(settings_from_params)
3539
end
3640

3741
def settings_from_params
38-
settings_params = params['settings'].deep_dup
42+
settings_params = params['settings'].deep_dup || {}
3943
if settings_params.respond_to?(:to_unsafe_h)
4044
settings_params.to_unsafe_h
4145
else

app/helpers/rails_settings_ui/settings_helper.rb

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,20 +70,15 @@ def message_for_default_value_missing
7070
content_tag(:span, I18n.t("settings.errors.default_missing"), class: "label label-warning")
7171
end
7272

73-
def get_collection_method
74-
case Rails::VERSION::STRING
75-
when /4\.0\.\d+/ || /3\..*/
76-
:all
77-
else
78-
:get_all
79-
end
80-
end
81-
8273
def default_value_for_setting(setting_name)
8374
RailsSettingsUi.defaults_for_settings.with_indifferent_access[setting_name.to_sym]
8475
end
8576

8677
def all_settings
87-
RailsSettingsUi.settings_klass.public_send(get_collection_method)
78+
stored_settings = RailsSettingsUi.settings_klass.public_send(:all).each_with_object({}) do |s, hsh|
79+
hsh[s.var] = s.value
80+
end.with_indifferent_access
81+
82+
stored_settings.merge(RailsSettingsUi.default_settings.merge(stored_settings))
8883
end
8984
end

config/locales/en.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
en:
22
errors:
3-
form_hash?: Invalid hash
4-
int?: Invalid numeric
5-
float?: Invalid numeric
3+
invalid_hash: Invalid hash
4+
invalid_numeric: Invalid numeric
65
settings:
76
index:
87
title: Settings

lib/rails-settings-ui.rb

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
require 'rails-settings-ui/route_delegator'
44
require 'rails-settings-ui/version'
55

6-
require "rails-settings-ui/settings_form_validator"
7-
require "rails-settings-ui/settings_form_coercible"
6+
require "rails-settings-ui/type_converter"
87

98
module RailsSettingsUi
109
mattr_accessor :parent_controller
@@ -45,12 +44,21 @@ def settings_klass
4544
settings_class.constantize
4645
end
4746

47+
def setting_config(name)
48+
defined_fields = RailsSettingsUi.settings_klass.public_send(:all).defined_fields
49+
defined_fields.find { |s| s[:key] == name }
50+
end
51+
4852
def default_settings
49-
if Gem.loaded_specs['rails-settings-cached'].version.to_s >= '0.6.0'
50-
settings = RailsSettings::Default.instance.with_indifferent_access
53+
rsc_version = Gem.loaded_specs['rails-settings-cached'].version.to_s
54+
55+
if rsc_version >= '2.7.0'
56+
defined_fields = RailsSettingsUi.settings_klass.public_send(:all).defined_fields
57+
settings = defined_fields.each_with_object({}) { |s, hsh| hsh[s[:key]] = s[:default] }.with_indifferent_access
5158
settings.reject { |name, _description| ignored_settings.include?(name.to_sym) }
5259
else
53-
RailsSettingsUi.settings_klass.defaults
60+
settings = RailsSettings::Default.instance.with_indifferent_access
61+
settings.reject { |name, _description| ignored_settings.include?(name.to_sym) }
5462
end
5563
end
5664
end
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
require_relative "value_types/string"
2+
require_relative "value_types/symbol"
3+
require_relative "value_types/fixnum"
4+
require_relative "value_types/hash"
5+
require_relative "value_types/duration"
6+
require_relative "value_types/float"
7+
require_relative "value_types/array"
8+
require_relative "value_types/boolean"
9+
10+
module RailsSettingsUi
11+
class UnknownDefaultValueType < StandardError;end
12+
13+
class TypeConverter
14+
VALUE_TYPES_MAP = {
15+
String => RailsSettingsUi::ValueTypes::String,
16+
Symbol => RailsSettingsUi::ValueTypes::Symbol,
17+
Fixnum => RailsSettingsUi::ValueTypes::Fixnum,
18+
# ActiveSupport::HashWithIndifferentAccess => RailsSettingsUi::ValueTypes::Hash,
19+
ActiveSupport::Duration => RailsSettingsUi::ValueTypes::Float,
20+
Float => RailsSettingsUi::ValueTypes::Float,
21+
Array => RailsSettingsUi::ValueTypes::Array,
22+
FalseClass => RailsSettingsUi::ValueTypes::Boolean,
23+
TrueClass => RailsSettingsUi::ValueTypes::Boolean,
24+
boolean: RailsSettingsUi::ValueTypes::Boolean,
25+
string: RailsSettingsUi::ValueTypes::String,
26+
integer: RailsSettingsUi::ValueTypes::Fixnum,
27+
float: RailsSettingsUi::ValueTypes::Float,
28+
array: RailsSettingsUi::ValueTypes::Array,
29+
hash: RailsSettingsUi::ValueTypes::Hash
30+
}
31+
32+
def self.cast(settings)
33+
errors = {}
34+
settings.each do |name, value|
35+
sc = RailsSettingsUi.setting_config(name.to_s)
36+
type = setting_value_type(name, value, sc)
37+
settings[name] = type.cast
38+
if type.errors.any?
39+
errors[name.to_sym] = type.errors
40+
end
41+
end
42+
settings = set_non_presented_settings(settings)
43+
44+
settings[:errors] = errors
45+
settings
46+
end
47+
48+
def self.setting_value_type(name, value, setting_config)
49+
default_setting_value_type = if setting_config[:type].nil? || setting_config[:type] == :string
50+
setting_config[:default].class
51+
else
52+
setting_config[:type]
53+
end
54+
55+
unless VALUE_TYPES_MAP.keys.include?(default_setting_value_type)
56+
raise RailsSettingsUi::UnknownDefaultValueType,
57+
"Unknown default value type #{default_setting_value_type} for #{name}"
58+
end
59+
60+
# puts "--- #{name}: #{default_setting_value_type} ---"
61+
setting_value_type_class = VALUE_TYPES_MAP[default_setting_value_type]
62+
setting_value_type_class.new(value)
63+
end
64+
65+
def self.set_non_presented_settings(settings)
66+
RailsSettingsUi.default_settings.each do |name, value|
67+
if !settings[name.to_sym].present?
68+
if [TrueClass, FalseClass].include?(value.class)
69+
settings[name.to_sym] = false
70+
elsif [Array].include?(value.class)
71+
settings[name.to_sym] = []
72+
end
73+
end
74+
end
75+
settings
76+
end
77+
end
78+
end
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
require_relative "base"
2+
3+
module RailsSettingsUi
4+
module ValueTypes
5+
class Array < RailsSettingsUi::ValueTypes::Base
6+
def cast
7+
# Array presented in checkboxes
8+
if ["Hash", "ActiveSupport::HashWithIndifferentAccess"].include?(value.class.name)
9+
value.keys.map!(&:to_sym)
10+
elsif value.class.name == 'ActionController::Parameters'
11+
value.reject{|_,v| v!='on' }.keys.map!(&:to_sym)
12+
# or in select tag
13+
else
14+
value.to_sym
15+
end
16+
end
17+
end
18+
end
19+
end

0 commit comments

Comments
 (0)