Ruby on Rails – 存储应用程序配置

我有一个相对简单的Rails应用程序,我想存储管理员用户可以在应用程序运行时更改的各种配置设置,例如,允许对post发表评论或更改日期的显示格式。

我知道我可以在environment.rb文件中存储常量等,但是这些似乎只在重新启动服务器时加载。

是否有另一个地方我可以定义这些信息,或者将它保存在数据库中会更好吗?

任何建议表示赞赏

谢谢。

您可以使用数据库。 创建一个单独的表“设置”,用于存储所需的键/值参数。 此解决方案的缺点是性能损失(每次需要设置时查询DB)。 要解决此问题,您可以通过“cache_money”等缓存读取/写入,或使用“Rails.cache”创建自己的缓存

你可以使用rails-settings-cached gem,它是rails-settings gem的一个分支(由Yi-Ru Lin在另一个答案中链接)。

设置完成后,您将能够执行以下操作:

Setting.foo = 123 Setting.foo # returns 123 

您还可以管理模型上的设置,例如:

 user.settings.color = :red user.settings.color # returns :red 

试着看它可能就是你需要的。

http://github.com/ledermann/rails-settings

最好的方法是使用数据库表。 每行应包含关键字和值。 Simples。

我已经使用了app_config gem一段时间了,但它失败了rails 2.3.9(也可能还有rails 3.x),所以我发现这个博客提到rails-settings和配置 ,rails-settings在DB中存储值,但配置内置了名称空间。 我没试过,但我想我会切换到rails-settings。

我现在注意到,Yi-Ru Lin提到的rails-settings的分支似乎比其他rails-settings更有特色

贵族

对于rails 4,如果您使用的是postgresql,则可以使用HStore ,它就像一个可序列化的属性,但您可以使用它进行SQL查询。

对于rails 3,您可以使用activerecord-postgres-hstore gem。

我尝试了https://github.com/huacnlee/rails-settings-cached ,但它没有按照描述的那样工作。 显然作者忘了在gem使用说明中提到一些额外的调整。 我没有为设置操作编写控制器。

相反,我成功地利用了https://github.com/paulca/configurable_engine – 尽管存在一些小问题,但这个gem比rails-settings-cached更合理。

configurable_engine gem有一个缺点:它具有模糊且不方便的硬编码路径。 gem的作者答应纠正它 ,但说他目前没有时间。

因此,只需创建自己的路线即可轻松解决此问题。 这是我的代码(添加以使这个gem真正起作用):

的routes.rb

  namespace :admin do resources :configurables, only: [:index, :show, :edit, :update, :destroy] end 

管理员/ configurables_controller.rb

 class Admin::ConfigurablesController < Admin::ApplicationController # include the engine controller actions include ConfigurableEngine::ConfigurablesController before_action :set_configurable, only: [:show, :edit, :update, :destroy] def index @configurables = (Configurable.all.size > 0 ? Configurable.all : []) + (Configurable.defaults.keys - Configurable.all.collect { |c| c.name }) end def show end def edit new = params[:new] end def new respond_to do |format| name = params[:name] if name @configurable = Configurable.create!(name: name, value: nil) if @configurable format.html { redirect_to edit_admin_configurable_path(@configurable, new: true), notice: 'The setting was successfully created.' } else format.html { redirect_to admin_configurables_url, notice: 'Failed to create the setting.' } end else format.html { redirect_to admin_configurables_url, notice: 'The name of the new setting was not specified.' } end end end def update respond_to do |format| if @configurable.update(configurable_params) format.html { redirect_to [:admin, @configurable], notice: 'The setting was successfully updated.' } format.json { render :show, status: :ok, location: @configurable } else format.html { render :edit } format.json { render json: @configurable.errors, status: :unprocessable_entity } end end end def destroy @configurable.destroy respond_to do |format| format.html { redirect_to admin_configurables_url, notice: 'The setting was successfully destroyed.' } format.json { head :no_content } end end private # Use callbacks to share common setup or constraints between actions. def set_configurable @configurable = Configurable.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def configurable_params params.require(:configurable).permit(:name, :value) end end 

index.html.erb

 

Settings

<% @configurables.each do |configurable| %> <% if configurable.try(:name) %> <% else %> <% end %> <% end %>
Name
<%= Configurable.defaults[configurable.name][:name]%> <%= link_to 'Show', [:admin, configurable] %> <%= link_to 'Edit', edit_admin_configurable_path(configurable) %> <%= link_to 'Destroy', [:admin, configurable], method: :delete, data: { confirm: 'Are you sure?' } %><%= Configurable.defaults[configurable][:name] %> <%= link_to 'Create', new_admin_configurable_path(name: configurable) %>

edit.html.erb

 

Editing <%= @new ? "new " : "" %>setting

<%= render 'form', configurable: @configurable %> <%= link_to 'Show', [:admin, @configurable] %> | <%= link_to 'Back', admin_configurables_path %>

show.html.erb

 

Name: <%= Configurable.defaults[@configurable.name][:name] %>

Value: <%= @configurable.value %>

<%= link_to 'Edit', edit_admin_configurable_path(@configurable) %> | <%= link_to 'Back', admin_configurables_path %>

_form.html.erb

 <%= form_for([:admin, configurable]) do |f| %> 
<%= f.label "Name" %> <%= Configurable.defaults[@configurable.name][:name] %>
<%= f.label "Value" %> <%= f.text_area :value %>
<%= f.submit "Submit" %>
<% end %>

由于硬编码路由,我的控制器不完全符合REST,但它非常接近。 我的new动作实际上创建了一个(数据库存储的)设置(仅覆盖其yml文件值)。

因此,添加到gem描述代码中的此代码可让您实际使用运行时可更改的RoR设置。

gem需要您事先在yml文件中设置一些默认值,您可以在运行时稍后覆盖它们。 但是你不能在运行时创建一个新设置(not-yml-file-existent) – 只修改一个存在的(在yml文件中) – 这是非常合乎逻辑的。

或者您可以恢复(在运行时)任何设置的默认值(通过删除其数据库存储的覆盖值)。

检查此代码以使用Rails 5。