# Rails Settings Cached This a plugin that makes managing a table of global key, value pairs easy. Think of it like a global Hash stored in your database, that uses simple ActiveRecord like methods for manipulation. Keep track of any global setting that you dont want to hard code into your rails app. You can store any kind of object. Strings, numbers, arrays, or any object. > 🚨 BREAK CHANGES WARNING: > rails-settings-cached 2.x has redesign the API, the new version will compatible with the stored setting values by older version. > When you wants to upgrade 2.x, you must read the README again, and follow guides to change your Setting model. ## Status [![Gem Version](https://badge.fury.io/rb/rails-settings-cached.svg)](https://rubygems.org/gems/rails-settings-cached) [![CI Status](https://travis-ci.org/huacnlee/rails-settings-cached.svg)](http://travis-ci.org/huacnlee/rails-settings-cached) [![Code Climate](https://codeclimate.com/github/huacnlee/rails-settings-cached/badges/gpa.svg)](https://codeclimate.com/github/huacnlee/rails-settings-cached) [![codecov.io](https://codecov.io/github/huacnlee/rails-settings-cached/coverage.svg?branch=master)](https://codecov.io/github/huacnlee/rails-settings-cached?branch=master) ## Setup Edit your Gemfile: ```ruby gem "rails-settings-cached" ``` Generate your settings: ```bash $ rails g settings:install ``` If you want custom model name: ```bash $ rails g settings:install ``` Or use a custom name: ```bash $ rails g settings:install SiteConfig ``` You will get `app/models/setting.rb` ```rb class Setting < RailsSettings::Base # cache_prefix { "v1" } field :host, default: "http://example.com" field :readonly_item, type: :integer, default: 100, readonly: true field :user_limits, type: :integer, default: 20 field :admin_emails, type: :array, default: %w[admin@rubyonrails.org] field :captcha_enable, type: :boolean, default: 1 field :notification_options, type: :hash, default: { send_all: true, logging: true, sender_email: "foo@bar.com" } end ``` You must use `field` method to statement the setting keys, otherwice you can't use it. Now just put that migration in the database with: ```bash rake db:migrate ``` ## Usage The syntax is easy. First, lets create some settings to keep track of: ```ruby irb > Setting.host "http://example.com" irb > Setting.host = "https://your-host.com" irb > Setting.host "https://your-host.com" irb > Setting.user_limits 20 irb > Setting.user_limits = "30" irb > Setting.user_limits 30 irb > Setting.user_limits = 45 irb > Setting.user_limits 45 irb > Setting.captcha_enable 1 irb > Setting.captcha_enable? true irb > Setting.captcha_enable = "0" irb > Setting.captcha_enable false irb > Setting.captcha_enable = "1" irb > Setting.captcha_enable true irb > Setting.captcha_enable = "false" irb > Setting.captcha_enable false irb > Setting.captcha_enable = "true" irb > Setting.captcha_enable true irb > Setting.captcha_enable? true irb > Setting.admin_emails ["admin@rubyonrails.org"] irb > Setting.admin_emails = %w[foo@bar.com bar@dar.com] irb > Setting.admin_emails ["foo@bar.com", "bar@dar.com"] irb > Setting.admin_emails = "huacnlee@gmail.com,admin@admin.com\nadmin@rubyonrails.org" irb > Setting.admin_emails ["huacnlee@gmail.com", "admin@admin.com", "admin@rubyonrails.org"] irb > Setting.notification_options { send_all: true, logging: true, sender_email: "foo@bar.com" } irb > Setting.notification_options = { sender_email: "notice@rubyonrails.org" } irb > Setting.notification_options { sender_email: "notice@rubyonrails.org" } ``` ### Caching flow: ``` Setting.host -> Check Cache -> Exist - Get value of key for cache -> Return | Fetch all key and values from DB -> Write Cache -> Get value of key for cache -> return | Return default value or nil ``` In each Setting keys call, we will load the cache/db and save in Thread.current for avoid hit cache/db. Each key update will expires the cache, so do not add some frequent update key. ## Change cache key Some times you may need to force update cache, now you can use `cache_prefix` ```ruby class Setting < RailsSettings::Base cache_prefix { "you-prefix" } ... end ``` ----- ## How to manage Settings in admin interface? If you want create an admin interface to editing the Settings, you can try methods in follow: config/routes.rb ```rb namespace :admin do resources :settings end ``` app/controllers/admin/settings_controller.rb ```rb module Admin class SettingsController < ApplicationController before_action :get_setting, only: [:edit, :update] def show end def create setting_params.keys.each do |key| next if key.to_s == "site_logo" Setting.send("#{key}=", setting_params[key].strip) unless setting_params[key].nil? end redirect_to admin_settings_path(notice: "Setting was successfully updated.") end private def setting_params params.require(:setting).permit(:host, :user_limits, :admin_emails, :captcha_enable, :notification_options) end end end ``` app/views/admin/settings/show.html.erb ```erb <%= form_for(Setting.new, url: admin_settings_path) do |f| %>
<%= f.text_field :host, value: Setting.host, class: "form-control", placeholder: "http://localhost" %>
<%= f.text_area :admin_emails, value: Setting.admin_emails.join("\n"), class: "form-control" %>
<%= f.text_area :notification_options, value: YAML.dump(Setting.notification_options), class: "form-control", style: "height: 180px;" %>
Use YAML format to config the SMTP_html <% end %> ``` ## Use case: - [ruby-china/ruby-china](https://github.com/ruby-china/ruby-china)