rails settings cached
该宝石将使管理全局密钥的表,值对。可以将其视为存储在您的数据库中的全局哈希,它使用了简单的ActivereCord进行操作的方法。跟踪您不想将其硬代码纳入Rails应用程序的任何全局设置。
安装
编辑您的Gemfile:
$ bundle add rails-settings-cached
生成您的设置:
$ rails g settings:install # Or use a custom name: $ rails g settings:install AppConfig
您将获得app/models/setting.rb
class Setting < RailsSettings :: Base # cache_prefix { \"v1\" } scope :application do field :app_name , default : \"Rails Settings\" , validates : { presence : true , length : { in : 2 .. 20 } } field :host , default : \"http://*ex*am*ple.com\" , readonly : true field :default_locale , default : \"zh-CN\" , validates : { presence : true , inclusion : { in : %w[ zh-CN en jp ] } } , option_values : %w[ en zh-CN jp ] , help_text : \"Bla bla ...\" field :admin_emails , type : :array , default : %w[ admin@rubyonrails.org ] # lambda default value field :welcome_message , type : :string , default : -> { \"welcome to #{ self . app_name } \" } , validates : { length : { maximum : 255 } } # Override array separator, default: /[\\n,]/ split with \\n or comma. field :tips , type : :array , separator : /[ \\n ]+/ end scope :limits do field :user_limits , type : :integer , default : 20 field :exchange_rate , type : :float , default : 0.123 field :captcha_enable , type : :boolean , default : true end field :notification_options , type : :hash , default : { send_all : true , logging : true , sender_email : \"foo@bar.com\" } field :readonly_item , type : :integer , default : 100 , readonly : true end
您必须使用field方法来对设置键进行声明,否则您不能使用它。
scope方法允许您对admin UI的键进行分组。
现在只将该迁移放在数据库中:
$ rails db:migrate
用法
语法很容易。首先,让我们创建一些设置以跟踪:
rails settings cached\”
irb > Setting.app_name
\” rails settings cached \”
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\”
}\”>
irb > Setting . host \"http://*ex*am*ple.com\" irb > Setting . app_name \"Rails Settings\" irb > Setting . app_name = \" rails settings cached \" irb > Setting . app_name \" rails settings cached \" 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 \\n admin@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\" }
获取定义的字段
版本2.3+
# Get all keys Setting . keys => [ \"app_name\" , \"host\" , \"default_locale\" , \"readonly_item\" ] # Get editable keys Setting . editable_keys => [ \"app_name\" , \"default_locale\" ] # Get readonly keys Setting . readonly_keys => [ \"host\" , \"readonly_item\" ] # Get field Setting . get_field ( \"host\" ) => { scope : :application , key : \"host\" , type : :string , default : \"http://*ex*am*ple.com\" , readonly : true } Setting . get_field ( \"app_name\" ) => { scope : :application , key : \"app_name\" , type : :string , default : \"Rails Settings\" , readonly : false } Setting . get_field ( :user_limits ) => { scope : :limits , key : \"user_limits\" , type : :integer , default : 20 , readonly : false } # Get field options Setting . get_field ( \"default_locale\" ) [ :options ] => { option_values : %w[ en zh-CN jp ] , help_text : \"Bla bla ...\" }
定制类型用于设置
自:2.9.0
您可以通过RailsSettings::Fields模块编写自定义字段类型。
例如
module RailsSettings module Fields class YesNo < :: RailsSettings :: Fields :: Base def serialize ( value ) case value when true then \"YES\" when false then \"NO\" else raise StandardError , \'invalid value\' end end def deserialize ( value ) case value when \"YES\" then true when \"NO\" then false else nil end end end end end
现在,您可以在设置中使用yes_no类型:
class Setting field :custom_item , type : :yes_no , default : \'YES\' end
irb > Setting . custom_item = \'YES\' irb > Setting . custom_item true irb > Setting . custom_item = \'NO\' irb > Setting . custom_item false
获取所有定义的字段
版本2.7.0+
您可以使用defined_fields方法在设置中获取所有定义的字段。
# Get editable fields and group by scope editable_fields = Setting . defined_fields . select { | field | ! field [ :readonly ] } . group_by { | field | field [ :scope ] }
验证
您可以使用validates选项来特殊轨道验证字段。
class Setting < RailsSettings :: Base # cache_prefix { \"v1\" } field :app_name , default : \"Rails Settings\" , validates : { presence : true , length : { in : 2 .. 20 } } field :default_locale , default : \"zh-CN\" , validates : { presence : true , inclusion : { in : %w[ zh-CN en jp ] , message : \"is not included in [zh-CN, en, jp]\" } } end
现在,验证将在记录上工作:
irb > Setting . app_name = \"\" ActiveRecord :: RecordInvalid : ( Validation failed : App name can \' t be blank ) irb > Setting . app_name = \"Rails Settings\" \"Rails Settings\" irb > Setting . default_locale = \"zh-TW\" ActiveRecord :: RecordInvalid : ( Validation failed : Default locale is not included in [ zh - CN , en , jp ] ) irb > Setting . default_locale = \"en\" \"en\"
通过save / valid?方法:
setting = Setting . find_or_initialize_by ( var : :app_name ) setting . value = \"\" setting . valid? # => false setting . errors . full_messages # => [\"App name can\'t be blank\", \"App name too short (minimum is 2 characters)\"] setting = Setting . find_or_initialize_by ( var : :default_locale ) setting . value = \"zh-TW\" setting . save # => false setting . errors . full_messages # => [\"Default locale is not included in [zh-CN, en, jp]\"] setting . value = \"en\" setting . valid? # => true
在轨道中使用设置初始化:
在version 2.3+您可以在初始化导轨之前使用设置。
例如config/initializers/devise.rb
Devise . setup do | config | if Setting . omniauth_google_client_id . present? config . omniauth :google_oauth2 , Setting . omniauth_google_client_id , Setting . omniauth_google_client_secret end end
class Setting < RailsSettings :: Base field :omniauth_google_client_id , default : ENV [ \"OMNIAUTH_GOOGLE_CLIENT_ID\" ] field :omniauth_google_client_secret , default : ENV [ \"OMNIAUTH_GOOGLE_CLIENT_SECRET\" ] end
Readonly字段
您可能还需要在Rails初始化之前使用设置:
config/environments/*.rb
如果您想这样做,则设置字段必须具有readonly: true 。
例如:
class Setting < RailsSettings :: Base field :mailer_provider , default : ( ENV [ \"mailer_provider\" ] || \"smtp\" ) , readonly : true field :mailer_options , type : :hash , readonly : true , default : { address : ENV [ \"mailer_options.address\" ] , port : ENV [ \"mailer_options.port\" ] , domain : ENV [ \"mailer_options.domain\" ] , user_name : ENV [ \"mailer_options.user_name\" ] , password : ENV [ \"mailer_options.password\" ] , authentication : ENV [ \"mailer_options.authentication\" ] || \"login\" , enable_starttls_auto : ENV [ \"mailer_options.enable_starttls_auto\" ] } end
配置/环境/生产.rb
# You must require_relative directly in Rails 6.1+ in config/environments/production.rb require_relative \"../../app/models/setting\" Rails . application . configure do config . action_mailer . delivery_method = :smtp config . action_mailer . smtp_settings = Setting . mailer_options . deep_symbolize_keys end
提示:您还可以按照此文件来重写ActionMailer的mail方法,以便从启动导轨后设置配置邮件选项。
https://github*.**com/ruby-china/homeland/blob/main/app/mailers/application_mailer.rb#l19
缓存流:
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
在每个设置键调用中,我们将加载缓存/db并保存在ActiveSupport :: CurrentAttributes中,以避免击中缓存/DB。
每个密钥更新将过期缓存,因此请勿添加一些频繁的更新密钥。
更改缓存键
有时您可能需要强制更新缓存,现在您可以使用cache_prefix
class Setting < RailsSettings :: Base cache_prefix { \"you-prefix\" } ... end
在测试中,您需要添加Setting.clear_cache 。每种测试用例Clear_cache:
class ActiveSupport :: TestCase teardown do Setting . clear_cache end end
如何管理管理接口中的设置?
如果要创建管理界面以编辑设置,则可以尝试以下方法:
config/routes.rb
namespace :admin do resource :settings end
App/Controllers/admin/settings_controller.rb
module Admin class SettingsController < ApplicationController def create @errors = ActiveModel :: Errors . new setting_params . keys . each do | key | next if setting_params [ key ] . nil? setting = Setting . new ( var : key ) setting . value = setting_params [ key ] . strip unless setting . valid? @errors . merge! ( setting . errors ) end end if @errors . any? render :new end setting_params . keys . each do | key | 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
<%= form_for(Setting.new, url: admin_settings_path) do |f| %> <% if @errors.any? %> < div class =\" alert alert-block alert-danger \" > < ul > <% @errors . full_messages . each do | msg | %> < li > <%= msg %> </ li > <% end %> </ ul > </ div > <% end %> < div class =\" form-group \" > < label class =\" control-label \" > Host </ label > <%= f . text_field :host , value : Setting . host , class : \"form-control\" , placeholder : \"http://*loca*lho*st\" %> </ div > < div class =\" form-group form-checkbox \" > < label > <%= f . check_box :captcha_enable , checked : Setting . captcha_enable? %> Enable/Disable Captcha </ label > </ div > < div class =\" form-group \" > < label class =\" control-label \" > Admin Emails </ label > <%= f . text_area :admin_emails , value : Setting . admin_emails . join ( \" \\n \" ) , class : \"form-control\" %> </ div > < div class =\" form-group \" > < label class =\" control-label \" > Notification options </ label > <%= f . text_area :notification_options , value : YAML . dump ( Setting . notification_options ) , class : \"form-control\" , style : \"height: 180px;\" %> < div class =\" form-text \" > Use YAML format to config the SMTP_html </ div > </ div > < div > <%= f . submit \'Update Settings\' %> </ div > <% end %>
特殊的缓存存储
您可以使用cache_store更改缓存存储,默认为Rails.cache 。
添加config/initializers/rails_settings.rb
RailsSettings . configure do self . cache_storage = ActiveSupport :: Cache :: RedisCacheStore . new ( url : \"redis://localhost:6379\" ) end
范围设置
休息更改警告:Rails-Settings-Sached 2.X已重新设计了API,新版本将与较旧版本的存储设置值兼容。当您想升级2.x时,必须再次阅读读书文件,然后遵循指南以更改设置模型。 0.x稳定分支:https://github.com/huacnlee/rails-settings-cached/tree/0.x
- 向后兼容以支持0.x范围的设置
适用于新项目 /轨道静止的新用户。 ActivereCord :: AttributeHods ::序列化是最佳选择。
这就是为什么轨道插座的2.x删除范围示波器设置功能的原因
