System Settings

System Settings is a Rails engine that adds settings functionality.

Initial setting values can be loaded from file and later edited in a System Settings provided admin panel.

Getting started

Add this line to your application's Gemfile:

gem 'system_settings'

And then execute:

$ bundle

Copy migrations:

$ bin/rails system_settings:install:migrations

And then run the migrations:

$ bin/rails db:migrate

Create settings file where all settings will be defined:

$ touch config/system_settings.rb

Add your first setting to config/system_settings.rb:

# String type values
string :default_mail_from, value: "Example Company <[email protected]>", description: "This email will be used for all outgoing emails"
string :date_format, value: "%Y-%m-%d"
string :default_locale, value: "en"

# Integer type values
integer :default_records_per_page, value: 25
integer :remainder_interval_in_hours, value: 48

# Decimal values
decimal :max_temp, value: 95.2

# Array type strings, integers and decimals
string_list :admin_emails, description: "Will receive alerts"
string_list :upload_allowed_extensions, value: ["docx", "pdf", "txt"]
integer_list :lucky_numbers, description: "Prime numbers are more effective", value: [2, 3, 5, 11]
decimal_list :allowed_multipliers, value: [12.3, 99, BigDecimal("-87")]

Load values from config/system_settings.rb into database:

$ ./bin/rails system_settings:load

Add System Settings admin panel to Rails routes:

Rails.application.routes.draw do
  mount SystemSettings::Engine, at: "/system_settings"
  # rest of your routes..
end

Final step. Access settings values anywhere in your code:

SystemSettings[:date_format] # => "%Y-%m-%d"
SystemSettings[:lucky_numbers] # => [2, 3, 5, 11]

# You can change setting's value like any other Rails model.
SystemSettings::Setting.find_by(name: "default_mail_from").update({value: "No-Reply <[email protected]>"})

Do not forget!

Before using System settings in production please protect the /system_settings endpoint with routing constraint. You can read more about it in Rails Guides: Rails Routing from the Outside In

Rails.application.routes.draw do
  mount SystemSettings::Engine, at: "/system_settings", constraints: AdminRoutingConstraint.new
  # rest of your routes..
end

Few more things

When you run ./bin/rails system_settings:load task it will read config/system_settings.rb file and add new entries to the database. If you would like to replace all values with the ones from the file then run ./bin/rails system_settings:reset

System Settings admin panel is precompiled at gem's build time. So it does not require any Javascript runtime and can be used with api-only Rails applications.

If you would like to store your settings somewhere else than config/system_settings.rb you can use ENV variable SYSTEM_SETTINGS_PATH to specify custom path.

Using System Settings in tests

Your test suite probably clears database before/after every test example. Fortunately is very easy to load fresh settings from configuration file. It can be done by running SystemSettings.load. It will persist all loaded settings. But if you would like to persist only a subset of loaded settings run SystemSettings.load(:one, :two, :three).

And if you modify settings values in test example you can reset to defaults with SystemSettings.reset_to_defaults.

Development

Optional development tools:

  • direnv - Unclutter your .profile

Required environment variables:

  • RAILS_VERSION
  • SQLITE3_VERSION

As System Settings gem is being developed to be compatible with multiple Rails versions, you need to set RAILS_VERSION and SQLITE3_VERSION environment variables when running bundle install or any ./bin/rails command. It is recommended to set these up using direnv and .envrc file.

Getting started with development: 1) RAILS_VERSION=5.2.3 SQLITE3_VERSION=1.4.1 bundle 2) RAILS_VERSION=5.2.3 SQLITE3_VERSION=1.4.1 ./bin/rails db:create db:migrate 3) RAILS_VERSION=5.2.3 SQLITE3_VERSION=1.4.1 ./bin/rails test

Build status

System Settings is being tested with Rails versions - 5.0, 5.1, 5.2, 6.0, rails repo master branch

Build Status Maintainability Test Coverage

License

The gem is available as open source under the terms of the MIT License.