ez-settings 0.2.4 → 0.5.0

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: ec5f2fa00686e7a7d220ff1944d4c0c481ccfb47b3a282285858ccc1c90468f0
4
- data.tar.gz: 8d5037d087086a8c045ef18ec9ce5c917892587f14a7bc567a47a623d7f0a711
3
+ metadata.gz: 75e0b44c2f8123c66e32bceef214e2fd3bd9b3e4f55029dcd5364f121b3cf8ec
4
+ data.tar.gz: 4f91b2c6c8616d70a65e1948675aa9dad7e7dd8f700571b6f442b464af97daa5
5
5
  SHA512:
6
- metadata.gz: 4c5d9592cd289a2acd0683154eea446b3d8330adf9e0effca9dbe68129cd76312c8ccf34d8d60a6c1fbb109ad7f5aae223f0e8d3dd850369c18be991c1dbff4b
7
- data.tar.gz: 87773d528bcc1f72c362aa3d77c568591c8311e6db673feb84bf004ce443731c3a2a182e2c0667b28c2332aa5ac828101c6025b654e4b5bd10149f214119fc24
6
+ metadata.gz: d531bb45eca96b1b81697f7dd8b59ce7b0955841c84a5c4e509966c787c2f55832a023ee8e7557445e8d26187e3dd44dad425dc41e2bf2eda38e9c501f2203df
7
+ data.tar.gz: 8296f4bcafd0d88f87d40620f5f921be69a9a87285e5163a4987a6cc1a5cef0e85a9f41481905809694d4b14c88ddc1fd0478c894d50712252de18f420edaf33
data/README.md CHANGED
@@ -9,10 +9,6 @@
9
9
  - Convetion over configuration principles.
10
10
  - Depends on [ez-core](https://github.com/ez-engines/ez-core)
11
11
 
12
- If you are boring to read all this stuff maybe this video motivates you:
13
-
14
- [YouTube demonstrates how easy we integrated ez-settings for our pivorak-web-app only by ±50 lines of code](https://www.youtube.com/watch?v=TiX0QDHEaKA&feature=youtu.be)
15
-
16
12
  ## Installation
17
13
  Add this line to your application's Gemfile:
18
14
 
@@ -38,7 +34,7 @@ and `bundle install`
38
34
 
39
35
  Generates initializer config file and I18n yaml file with english keys
40
36
 
41
- `config/ez_settings.rb`
37
+ `config/initializers/ez_settings.rb`
42
38
  ```ruby
43
39
  # By default engine try to inherit from ApplicationController, but you could change this:
44
40
  # Ez::Settings.config.base_controller = 'Admin::BaseController'
@@ -82,11 +78,18 @@ end
82
78
  # After defining settings interface groups/keys you need to configure it:
83
79
  app.configure do |config|
84
80
  # Backend adapter to store all settings
85
- config.backend = Ez::Settings::Backend::FileSystem.new(Rails.root.join('config', 'settings.yml'))
86
- # Redis is also supported:
87
- # config.backend = Ez::Settings::Backend::Redis.new('config')
81
+ config.backend = Ez::Settings::Backend::ActiveRecord.new
82
+ # and DB table name that you can change as well
83
+ # config.active_record_table_name = :ez_settings_store
84
+
85
+ # YAML filesystem
86
+ # config.backend = Ez::Settings::Backend::FileSystem.new(Rails.root.join('config', 'settings.yml'))
88
87
 
89
- # Default path for redirect in controller
88
+ # Redis
89
+ # require 'redis'
90
+ # config.backend = Ez::Settings::Backend::Redis.new(Redis.current, namespace: 'myapp')
91
+
92
+ # Default path for redirect in the settings controller
90
93
  config.default_path = '/admin/settings'
91
94
 
92
95
  # Pass your custom css classes through css_map config
@@ -139,6 +142,19 @@ Ez::Registry.in(:settings_interfaces, by: 'YourAppName') do |registry|
139
142
  end
140
143
  ```
141
144
 
145
+
146
+ ### Database storage as backend (ActiveRecord)
147
+
148
+ You can use migrations generator
149
+
150
+ `rails generate ez:settings:active_record_migrations`
151
+
152
+ Generates migration for `ez_settings_store` table.
153
+
154
+ `rails db:migrate`
155
+
156
+
157
+
142
158
  ### Routes
143
159
  `config/routes.rb`
144
160
 
@@ -229,10 +245,13 @@ If you need, create locale file with this structure:
229
245
  groups:
230
246
  general:
231
247
  label: General
248
+ description: General settings of your application
232
249
  admin:
233
250
  label: Admin
251
+ description: Admin area settings
234
252
  showcase:
235
253
  label: Showcase
254
+ description: Just an example of possible settings UI elements
236
255
  keys:
237
256
  string:
238
257
  label: String
@@ -250,14 +269,16 @@ If you need, create locale file with this structure:
250
269
 
251
270
  ## TODO
252
271
  This features will be implemented in upcoming 0.2 and 0.3 releases:
253
- - JSON API endpoints and `ez_settings_api_for` routes helper
254
- - Scoped settings (`:scope_id`, `:scope_type`)
255
- - controller before actions as configured callbacks (for external usage)
256
- - Interface description (and show at UI)
257
- - Groups description (and show at UI)
258
- - Keys description (and show at UI)
259
- - Database storage as backend (ActiveRecord)
260
- - UI frameworks adapters: bootsrap3, bootstrap4, foundation, semantic, etc.
272
+ - [] JSON API endpoints and `ez_settings_api_for` routes helper
273
+ - [] Scoped settings (`:scope_id`, `:scope_type`)
274
+ - [] Controller before actions as configured callbacks (for external usage)
275
+ - [] Interface description (and show at UI)
276
+ - [] Groups description (and show at UI)
277
+ - [] Keys description (and show at UI)
278
+ - [] Database storage as backend (ActiveRecord)
279
+ - [] Backend#read method should receive app, group & key attributes and avoid loading all in case of SQL adapter
280
+ - [] UI frameworks adapters: bootsrap3, bootstrap4, foundation, semantic, etc.
281
+ - [X] Bug: Read only defaul values if ActiveRecord do not ready yet (migrations)
261
282
 
262
283
  ## Contributing
263
284
  Fork => Fix => MR warmly welcomed!
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  begin
2
4
  require 'bundler/setup'
3
5
  rescue LoadError
@@ -14,15 +16,15 @@ RDoc::Task.new(:rdoc) do |rdoc|
14
16
  rdoc.rdoc_files.include('lib/**/*.rb')
15
17
  end
16
18
 
17
- APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
19
+ APP_RAKEFILE = File.expand_path('spec/dummy/Rakefile', __dir__)
18
20
  load 'rails/tasks/engine.rake'
19
21
 
20
22
  load 'rails/tasks/statistics.rake'
21
23
 
22
24
  require 'bundler/gem_tasks'
23
25
 
24
- require "rspec/core/rake_task"
26
+ require 'rspec/core/rake_task'
25
27
 
26
28
  RSpec::Core::RakeTask.new(:spec)
27
29
 
28
- task :default => :spec
30
+ task default: :spec
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ez::Settings
2
4
  class BaseCell < Cell::ViewModel
3
5
  include RequestDispatcher
@@ -8,14 +10,15 @@ module Ez::Settings
8
10
  delegate :params, :request, to: :controller
9
11
  delegate :dynamic_css_map, to: :'interface.config'
10
12
 
11
- SCOPE = 'ez_settings'
12
- LABEL = 'label'
13
- INTERFACES = 'interfaces'
14
- GROUPS = 'groups'
15
- KEYS = 'keys'
16
- ACTIONS = 'actions'
17
- SAVE = 'save'
18
- CANCEL = 'cancel'
13
+ SCOPE = 'ez_settings'
14
+ LABEL = 'label'
15
+ DESCRIPTION = 'description'
16
+ INTERFACES = 'interfaces'
17
+ GROUPS = 'groups'
18
+ KEYS = 'keys'
19
+ ACTIONS = 'actions'
20
+ SAVE = 'save'
21
+ CANCEL = 'cancel'
19
22
 
20
23
  def self.form
21
24
  include ActionView::Helpers::FormHelper
@@ -43,27 +46,27 @@ module Ez::Settings
43
46
 
44
47
  def css_map
45
48
  {
46
- nav_label: 'ez-settings-nav-label',
47
- nav_menu: 'ez-settings-nav-menu',
48
- nav_menu_item: 'ez-settings-nav-menu-item',
49
- overview_page_wrapper: 'ez-settings-overview',
50
- overview_page_section: 'ez-settings-overview-section',
51
- overview_page_section_header: 'ez-settings-overview-section-header',
52
- overview_page_section_content: 'ez-settings-overview-section-content',
53
- overview_page_section_content_key: 'ez-settings-overview-section-content-key',
49
+ nav_label: 'ez-settings-nav-label',
50
+ nav_menu: 'ez-settings-nav-menu',
51
+ nav_menu_item: 'ez-settings-nav-menu-item',
52
+ overview_page_wrapper: 'ez-settings-overview',
53
+ overview_page_section: 'ez-settings-overview-section',
54
+ overview_page_section_header: 'ez-settings-overview-section-header',
55
+ overview_page_section_content: 'ez-settings-overview-section-content',
56
+ overview_page_section_content_key: 'ez-settings-overview-section-content-key',
54
57
  overview_page_section_content_value: 'ez-settings-overview-section-content-value',
55
- group_page_wrapper: 'ez-settings-group-wrapper',
56
- group_page_inner_wrapper: 'ez-settings-group-inner-wrapper',
57
- group_page_header: 'ez-settings-group-header',
58
- group_page_form_wrapper: 'ez-settings-group-form-wrapper',
59
- group_page_form_inner: 'ez-settings-group-form-inner',
60
- group_page_form_field_row: 'ez-settings-group-form-field-row',
61
- group_page_form_string_wrapper: 'ez-settings-group-form-string-wrapper',
62
- group_page_form_boolean_wrapper: 'ez-settings-group-form-boolean-wrapper',
63
- group_page_form_select_wrapper: 'ez-settings-group-form-select-wrapper',
64
- group_page_actions_wrapper: 'ez-settings-group-actions-wrapper',
65
- group_page_actions_save_button: 'ez-settings-group-actions-save-btn',
66
- group_page_actions_cancel_link: 'ez-settings-group-actions-cancel-link'
58
+ group_page_wrapper: 'ez-settings-group-wrapper',
59
+ group_page_inner_wrapper: 'ez-settings-group-inner-wrapper',
60
+ group_page_header: 'ez-settings-group-header',
61
+ group_page_form_wrapper: 'ez-settings-group-form-wrapper',
62
+ group_page_form_inner: 'ez-settings-group-form-inner',
63
+ group_page_form_field_row: 'ez-settings-group-form-field-row',
64
+ group_page_form_string_wrapper: 'ez-settings-group-form-string-wrapper',
65
+ group_page_form_boolean_wrapper: 'ez-settings-group-form-boolean-wrapper',
66
+ group_page_form_select_wrapper: 'ez-settings-group-form-select-wrapper',
67
+ group_page_actions_wrapper: 'ez-settings-group-actions-wrapper',
68
+ group_page_actions_save_button: 'ez-settings-group-actions-save-btn',
69
+ group_page_actions_cancel_link: 'ez-settings-group-actions-cancel-link'
67
70
  }.merge(interface.config.custom_css_map)
68
71
  end
69
72
 
@@ -71,10 +74,10 @@ module Ez::Settings
71
74
  context[:controller]
72
75
  end
73
76
 
74
- def group_link(group, options = {})
77
+ def group_link(group, _options = {})
75
78
  link_to i18n_group_label(group),
76
- group_path(group),
77
- class: css_for(:nav_menu_item, dynamic: "settings/#{group.name}")
79
+ group_path(group),
80
+ class: css_for(:nav_menu_item, dynamic: "settings/#{group.name}")
78
81
  end
79
82
 
80
83
  def group_path(group)
@@ -82,12 +85,17 @@ module Ez::Settings
82
85
  end
83
86
 
84
87
  def i18n_group_label(group)
85
- t(LABEL, scope: [SCOPE, INTERFACES, group.interface, GROUPS, group.name],
88
+ t(LABEL, scope: [SCOPE, INTERFACES, group.interface, GROUPS, group.name],
86
89
  default: group.name.to_s.humanize)
87
90
  end
88
91
 
92
+ def i18n_group_description(group)
93
+ t(DESCRIPTION, scope: [SCOPE, INTERFACES, group.interface, GROUPS, group.name],
94
+ default: group.name.to_s.humanize)
95
+ end
96
+
89
97
  def i18n_key_label(key)
90
- t(LABEL, scope: [SCOPE, INTERFACES, key.interface, GROUPS, key.group, KEYS, key.name],
98
+ t(LABEL, scope: [SCOPE, INTERFACES, key.interface, GROUPS, key.group, KEYS, key.name],
91
99
  default: key.name.to_s.humanize)
92
100
  end
93
101
  end
@@ -5,6 +5,7 @@
5
5
  div class=(css_for :group_page_inner_wrapper)
6
6
  div class=(css_for :group_page_header)
7
7
  = i18n_group_label(group)
8
+ p = i18n_group_description(group)
8
9
 
9
10
  div class=(css_for :group_page_form_wrapper)
10
11
  = simple_form_for store, as: :settings, url: form_url, method: :put do |f|
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ez::Settings
2
4
  class GroupCell < BaseCell
3
5
  form
@@ -11,16 +13,16 @@ module Ez::Settings
11
13
 
12
14
  def save_button(form)
13
15
  form.button :submit,
14
- t(LABEL, scope: [SCOPE, INTERFACES, model.interface, ACTIONS, SAVE],
15
- default: 'Save'),
16
- class: css_for(:group_page_actions_save_button)
16
+ t(LABEL, scope: [SCOPE, INTERFACES, model.interface, ACTIONS, SAVE],
17
+ default: 'Save'),
18
+ class: css_for(:group_page_actions_save_button)
17
19
  end
18
20
 
19
21
  def cancel_link
20
- link_to t(LABEL, scope: [SCOPE, INTERFACES, model.interface, ACTIONS,CANCEL],
22
+ link_to t(LABEL, scope: [SCOPE, INTERFACES, model.interface, ACTIONS, CANCEL],
21
23
  default: 'Cancel'),
22
- interface.config.default_path,
23
- class: css_for(:group_page_actions_cancel_link)
24
+ interface.config.default_path,
25
+ class: css_for(:group_page_actions_cancel_link)
24
26
  end
25
27
  end
26
28
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ez::Settings
2
4
  class IndexCell < BaseCell
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ez::Settings
2
4
  class KeyCell < BaseCell
3
5
  form
@@ -8,15 +10,15 @@ module Ez::Settings
8
10
 
9
11
  def html_options
10
12
  {
11
- label: i18n_key_label(model),
12
- as: model.type,
13
- collection: model.collection,
14
- include_blank: model.default.present?,
15
- required: model.required?,
16
- checked_value: true.to_s,
13
+ label: i18n_key_label(model),
14
+ as: model.type,
15
+ collection: model.collection,
16
+ include_blank: model.default.present?,
17
+ required: model.required?,
18
+ checked_value: true.to_s,
17
19
  unchecked_value: false.to_s,
18
- wrapper: model.wrapper,
19
- right_label: model.suffix,
20
+ wrapper: model.wrapper,
21
+ right_label: model.suffix,
20
22
  input_html: {
21
23
  min: model.min
22
24
  }
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ez::Settings
2
4
  class NavCell < BaseCell
3
5
  def nav_label
@@ -6,8 +8,8 @@ module Ez::Settings
6
8
 
7
9
  def settings_link
8
10
  link_to nav_label,
9
- interface.config.default_path,
10
- class: css_for(:nav_menu_item, dynamic: 'settings/')
11
+ interface.config.default_path,
12
+ class: css_for(:nav_menu_item, dynamic: 'settings/')
11
13
  end
12
14
  end
13
15
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ez
2
4
  module Settings
3
5
  class ApplicationController < Ez::Settings.config.base_controller.constantize
@@ -1,8 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ez
2
4
  module Settings
3
5
  class SettingsController < Ez::Settings::ApplicationController
4
6
  include Ez::Settings::RequestDispatcher
5
7
 
8
+ if Ez::Settings.config.controller_context
9
+ instance_exec(&Ez::Settings.config.controller_context)
10
+ end
11
+
6
12
  def index
7
13
  view :index
8
14
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ez
2
4
  module Settings
3
5
  module ApplicationHelper
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ez
4
+ module Settings
5
+ class ActiveRecordStore < Ez::Settings::ApplicationRecord
6
+ self.table_name = Ez::Settings.config.active_record_table_name || :ez_settings
7
+
8
+ validates :key, uniqueness: { scope: :group }
9
+ end
10
+ end
11
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ez
2
4
  module Settings
3
5
  class ApplicationRecord < ActiveRecord::Base
data/config/routes.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Ez::Settings::Engine.routes.draw do
2
4
  scope module: 'ez/settings' do
3
5
  root to: 'settings#index'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ez::Settings
2
4
  NotRegistredInterfaceError = Class.new(StandardError)
3
5
  NotRegistredGroupError = Class.new(StandardError)
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record'
4
+
5
+ module Ez::Settings
6
+ module Backend
7
+ class ActiveRecord
8
+ def read
9
+ return {} unless try_db_connection && check_settings_table
10
+
11
+ ActiveRecordStore.all.each_with_object({}) do |settings, hsh|
12
+ hsh[settings.group] ||= {}
13
+ hsh[settings.group][settings.key] = settings.value
14
+ end.deep_symbolize_keys
15
+ end
16
+
17
+ def write(data)
18
+ return unless try_db_connection && check_settings_table
19
+
20
+ group = data.keys[0]
21
+ pairs = data.values[0]
22
+ existing_settings = ActiveRecordStore.where(group: group, key: pairs.keys)
23
+ pairs.map do |key, value|
24
+ record(existing_settings, key, value) || ActiveRecordStore.new(group: group, key: key, value: value)
25
+ end.each(&:save!)
26
+ end
27
+
28
+ private
29
+
30
+ def record(existing_settings, key, value)
31
+ record = existing_settings.find { |r| r.key == key.to_s }
32
+
33
+ return unless record
34
+
35
+ record.tap { |r| r.value = value }
36
+ end
37
+
38
+ def try_db_connection
39
+ ::ActiveRecord::Base.connection
40
+ rescue ::ActiveRecord::NoDatabaseError
41
+ message('Database does not exist')
42
+ false
43
+ end
44
+
45
+ def check_settings_table
46
+ settings_table = Ez::Settings.config.active_record_table_name || :ez_settings
47
+ if ::ActiveRecord::Base.connection.data_source_exists?(settings_table)
48
+ return true
49
+ end
50
+
51
+ message("Table #{settings_table} does not exists. Please, check migrations")
52
+ false
53
+ end
54
+
55
+ def message(txt, level = 'WARN')
56
+ STDOUT.puts("[#{level}] Ez::Settings: #{txt}")
57
+ end
58
+ end
59
+ end
60
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'yaml'
2
4
  require 'active_support/hash_with_indifferent_access'
3
5
 
@@ -1,37 +1,36 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
- require 'redis'
3
4
  require 'active_support/hash_with_indifferent_access'
4
5
 
5
6
  module Ez::Settings
6
7
  module Backend
7
8
  class Redis
8
9
  PREFIX = 'ez:settings'
10
+ NAMESPACE = 'config'
11
+
12
+ attr_reader :connection, :namespace
9
13
 
10
- def initialize(namespace)
14
+ def initialize(connection, namespace: NAMESPACE)
15
+ @connection = connection
11
16
  @namespace = namespace
12
17
  end
13
18
 
14
19
  def read
15
- value = client.get(key)
20
+ value = connection.get(key)
16
21
  value.nil? ? {} : JSON.parse(value).deep_symbolize_keys
17
22
  end
18
23
 
19
24
  def write(data)
20
25
  new_data = read.merge(data)
21
- client.set(key, JSON.generate(new_data))
26
+ connection.set(key, JSON.generate(new_data))
22
27
  end
23
28
 
24
29
  private
25
30
 
26
- attr_reader :namespace
27
-
28
31
  def key
29
32
  @key ||= "#{PREFIX}:#{namespace}"
30
33
  end
31
-
32
- def client
33
- @client ||= ::Redis.current
34
- end
35
34
  end
36
35
  end
37
36
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ez/configurator'
2
4
 
3
5
  module Ez::Settings
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'cells-rails'
2
4
  require 'cells-slim'
3
5
  require 'simple_form'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'key'
2
4
  require_relative '../store'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ez::Settings
2
4
  class Interface
3
5
  class Key
@@ -21,8 +23,8 @@ module Ez::Settings
21
23
  end
22
24
 
23
25
  # Alias all boolean-like options to predicates methods, please
24
- alias_method :ui?, :ui
25
- alias_method :required?, :required
26
+ alias ui? ui
27
+ alias required? required
26
28
  end
27
29
  end
28
30
  end
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'interface/group'
2
4
  require_relative 'interface/key'
3
5
  require_relative 'store'
4
6
 
5
7
  require 'ez/configurator'
6
8
  require 'ez/settings/backend/file_system'
9
+ require 'ez/settings/backend/active_record'
7
10
 
8
11
  module Ez::Settings
9
12
  class Interface
@@ -29,11 +32,12 @@ module Ez::Settings
29
32
 
30
33
  def initialize(name)
31
34
  @name = name
32
- @keys, @groups = [], []
35
+ @keys = []
36
+ @groups = []
33
37
  end
34
38
 
35
39
  def define(&block)
36
- self.instance_eval(&block)
40
+ instance_eval(&block)
37
41
  end
38
42
 
39
43
  def group(name, options = {}, &block)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ez
2
4
  module Settings
3
5
  module RequestDispatcher
@@ -8,7 +10,7 @@ module Ez
8
10
 
9
11
  # TODO: add raise exception in nil
10
12
  Ez::Registry.data(:settings_interfaces).find do |interface|
11
- interface.name == params[:ez_settings_interface].to_sym
13
+ interface.name == params[:ez_settings_interface].to_sym
12
14
  end
13
15
  end
14
16
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ActionDispatch::Routing::Mapper
2
4
  def ez_settings_for(interface)
3
5
  defaults ez_settings_interface: interface do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_model'
2
4
 
3
5
  require 'ez/settings/config'
@@ -23,7 +25,7 @@ module Ez::Settings
23
25
  @errors = ActiveModel::Errors.new(self)
24
26
 
25
27
  group.keys.select(&:required?).each do |key|
26
- errors.add(key.name, "can't be blank") if self.send(key.name).blank?
28
+ errors.add(key.name, "can't be blank") if send(key.name).blank?
27
29
  end
28
30
  end
29
31
 
@@ -36,12 +38,12 @@ module Ez::Settings
36
38
  end
37
39
 
38
40
  def update(params)
39
- params.each { |key, value| self.public_send("#{key}=", value) }
41
+ params.each { |key, value| public_send("#{key}=", value) }
40
42
 
41
43
  validate
42
44
  return self unless errors.empty?
43
45
 
44
- on_change.call(changes(params)) if on_change
46
+ on_change&.call(changes(params))
45
47
 
46
48
  backend.write(schema)
47
49
 
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ez
2
4
  module Settings
3
- VERSION = '0.2.4'
5
+ VERSION = '0.5.0'
4
6
  end
5
7
  end
data/lib/ez/settings.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ez/settings/engine'
2
4
 
3
5
  require 'ez/registry'
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ez::Settings
4
+ class ActiveRecordMigrationsGenerator < Rails::Generators::Base
5
+ def create_migration
6
+ create_file "db/migrate/#{Time.now.strftime('%Y%m%d%H%M%S')}_create_ez_settings.rb",
7
+ "class CreateEzSettings < ActiveRecord::Migration[5.0]
8
+ def change
9
+ create_table :ez_settings do |t|
10
+ t.string :group, null: false
11
+ t.string :key, null: false
12
+ t.string :value, null: false
13
+
14
+ t.timestamps
15
+ end
16
+
17
+ add_index :ez_settings, :key
18
+ add_index :ez_settings, :group
19
+ add_index :ez_settings, [:key, :group], unique: true
20
+ end
21
+ end
22
+ "
23
+ end
24
+ end
25
+ end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ez::Settings
2
4
  class InstallGenerator < Rails::Generators::Base
3
5
  def create_initializer_file
4
- create_file "config/initializers/ez_settings.rb",
5
- "# By default engine try to inherit from ApplicationController, but you could change this:
6
+ create_file 'config/initializers/ez_settings.rb',
7
+ "# By default engine try to inherit from ApplicationController, but you could change this:
6
8
  # Ez::Settings.config.base_controller = 'Admin::BaseController'
7
9
  #
8
10
  # Then you should define settings interfaces (you can create as much as you need)
@@ -94,8 +96,8 @@ end"
94
96
  end
95
97
 
96
98
  def create_locale_file
97
- create_file "config/locales/ez_settings.en.yml",
98
- "en:
99
+ create_file 'config/locales/ez_settings.en.yml',
100
+ "en:
99
101
  ez_settings:
100
102
  label: Ez Settings
101
103
  interfaces:
@@ -103,16 +105,19 @@ end"
103
105
  label: App Settings
104
106
  actions:
105
107
  save:
106
- label: Save Settings
108
+ label: Update
107
109
  cancel:
108
- label: Cancel Settings
110
+ label: Cancel
109
111
  groups:
110
112
  general:
111
113
  label: General
114
+ description: General settings of your application
112
115
  admin:
113
116
  label: Admin
117
+ description: Admin area settings
114
118
  showcase:
115
119
  label: Showcase
120
+ description: Just an example of possible settings UI elements
116
121
  keys:
117
122
  string:
118
123
  label: String
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ez-settings
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Volodya Sveredyuk
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-02 00:00:00.000000000 Z
11
+ date: 2022-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ez-core
@@ -16,86 +16,72 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.1
19
+ version: 0.2.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.1
27
- - !ruby/object:Gem::Dependency
28
- name: rails
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 5.0.0
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: 5.0.0
26
+ version: 0.2.0
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: cells-rails
43
29
  requirement: !ruby/object:Gem::Requirement
44
30
  requirements:
45
31
  - - "~>"
46
32
  - !ruby/object:Gem::Version
47
- version: 0.0.8
33
+ version: 0.1.0
48
34
  type: :runtime
49
35
  prerelease: false
50
36
  version_requirements: !ruby/object:Gem::Requirement
51
37
  requirements:
52
38
  - - "~>"
53
39
  - !ruby/object:Gem::Version
54
- version: 0.0.8
40
+ version: 0.1.0
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: cells-slim
57
43
  requirement: !ruby/object:Gem::Requirement
58
44
  requirements:
59
45
  - - "~>"
60
46
  - !ruby/object:Gem::Version
61
- version: 0.0.5
47
+ version: 0.0.6
62
48
  type: :runtime
63
49
  prerelease: false
64
50
  version_requirements: !ruby/object:Gem::Requirement
65
51
  requirements:
66
52
  - - "~>"
67
53
  - !ruby/object:Gem::Version
68
- version: 0.0.5
54
+ version: 0.0.6
69
55
  - !ruby/object:Gem::Dependency
70
- name: redis
56
+ name: rails
71
57
  requirement: !ruby/object:Gem::Requirement
72
58
  requirements:
73
- - - "~>"
59
+ - - ">="
74
60
  - !ruby/object:Gem::Version
75
- version: '3.0'
61
+ version: 5.0.0
76
62
  type: :runtime
77
63
  prerelease: false
78
64
  version_requirements: !ruby/object:Gem::Requirement
79
65
  requirements:
80
- - - "~>"
66
+ - - ">="
81
67
  - !ruby/object:Gem::Version
82
- version: '3.0'
68
+ version: 5.0.0
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: simple_form
85
71
  requirement: !ruby/object:Gem::Requirement
86
72
  requirements:
87
73
  - - ">="
88
74
  - !ruby/object:Gem::Version
89
- version: 3.5.0
75
+ version: 5.0.1
90
76
  type: :runtime
91
77
  prerelease: false
92
78
  version_requirements: !ruby/object:Gem::Requirement
93
79
  requirements:
94
80
  - - ">="
95
81
  - !ruby/object:Gem::Version
96
- version: 3.5.0
82
+ version: 5.0.1
97
83
  - !ruby/object:Gem::Dependency
98
- name: sqlite3
84
+ name: capybara
99
85
  requirement: !ruby/object:Gem::Requirement
100
86
  requirements:
101
87
  - - ">="
@@ -109,7 +95,7 @@ dependencies:
109
95
  - !ruby/object:Gem::Version
110
96
  version: '0'
111
97
  - !ruby/object:Gem::Dependency
112
- name: rspec-rails
98
+ name: faker
113
99
  requirement: !ruby/object:Gem::Requirement
114
100
  requirements:
115
101
  - - ">="
@@ -123,7 +109,7 @@ dependencies:
123
109
  - !ruby/object:Gem::Version
124
110
  version: '0'
125
111
  - !ruby/object:Gem::Dependency
126
- name: pry-rails
112
+ name: fakeredis
127
113
  requirement: !ruby/object:Gem::Requirement
128
114
  requirements:
129
115
  - - ">="
@@ -137,7 +123,7 @@ dependencies:
137
123
  - !ruby/object:Gem::Version
138
124
  version: '0'
139
125
  - !ruby/object:Gem::Dependency
140
- name: simplecov
126
+ name: generator_spec
141
127
  requirement: !ruby/object:Gem::Requirement
142
128
  requirements:
143
129
  - - ">="
@@ -151,7 +137,7 @@ dependencies:
151
137
  - !ruby/object:Gem::Version
152
138
  version: '0'
153
139
  - !ruby/object:Gem::Dependency
154
- name: capybara
140
+ name: guard-rspec
155
141
  requirement: !ruby/object:Gem::Requirement
156
142
  requirements:
157
143
  - - ">="
@@ -179,7 +165,7 @@ dependencies:
179
165
  - !ruby/object:Gem::Version
180
166
  version: '0'
181
167
  - !ruby/object:Gem::Dependency
182
- name: faker
168
+ name: pry-rails
183
169
  requirement: !ruby/object:Gem::Requirement
184
170
  requirements:
185
171
  - - ">="
@@ -193,7 +179,7 @@ dependencies:
193
179
  - !ruby/object:Gem::Version
194
180
  version: '0'
195
181
  - !ruby/object:Gem::Dependency
196
- name: guard-rspec
182
+ name: rspec-rails
197
183
  requirement: !ruby/object:Gem::Requirement
198
184
  requirements:
199
185
  - - ">="
@@ -207,7 +193,7 @@ dependencies:
207
193
  - !ruby/object:Gem::Version
208
194
  version: '0'
209
195
  - !ruby/object:Gem::Dependency
210
- name: generator_spec
196
+ name: simplecov
211
197
  requirement: !ruby/object:Gem::Requirement
212
198
  requirements:
213
199
  - - ">="
@@ -221,7 +207,7 @@ dependencies:
221
207
  - !ruby/object:Gem::Version
222
208
  version: '0'
223
209
  - !ruby/object:Gem::Dependency
224
- name: fakeredis
210
+ name: sqlite3
225
211
  requirement: !ruby/object:Gem::Requirement
226
212
  requirements:
227
213
  - - ">="
@@ -259,10 +245,12 @@ files:
259
245
  - app/controllers/ez/settings/application_controller.rb
260
246
  - app/controllers/ez/settings/settings_controller.rb
261
247
  - app/helpers/ez/settings/application_helper.rb
248
+ - app/models/ez/settings/active_record_store.rb
262
249
  - app/models/ez/settings/application_record.rb
263
250
  - config/routes.rb
264
251
  - lib/ez/settings.rb
265
252
  - lib/ez/settings/accessors.rb
253
+ - lib/ez/settings/backend/active_record.rb
266
254
  - lib/ez/settings/backend/file_system.rb
267
255
  - lib/ez/settings/backend/redis.rb
268
256
  - lib/ez/settings/config.rb
@@ -274,12 +262,13 @@ files:
274
262
  - lib/ez/settings/routes.rb
275
263
  - lib/ez/settings/store.rb
276
264
  - lib/ez/settings/version.rb
265
+ - lib/generators/ez/settings/active_record_migrations_generator.rb
277
266
  - lib/generators/ez/settings/install_generator.rb
278
267
  homepage: https://github.com/ez-engines
279
268
  licenses:
280
269
  - MIT
281
270
  metadata: {}
282
- post_install_message:
271
+ post_install_message:
283
272
  rdoc_options: []
284
273
  require_paths:
285
274
  - lib
@@ -294,9 +283,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
294
283
  - !ruby/object:Gem::Version
295
284
  version: '0'
296
285
  requirements: []
297
- rubyforge_project:
298
- rubygems_version: 2.7.6
299
- signing_key:
286
+ rubygems_version: 3.2.15
287
+ signing_key:
300
288
  specification_version: 4
301
289
  summary: Easy settings engine for Rails app.
302
290
  test_files: []