我有一个相对简单的Rails应用程序,我想存储管理员用户在应用程序运行时可以更改的各种配置设置,例如,允许对帖子发表评论或更改日期的显示格式。
我知道我可以在environment.rb文件中存储常量等,但是这些似乎只在服务器重新启动时加载。
是否有其他地方可以定义此信息,还是将其保存在数据库中会更好?
任何建议表示赞赏。
感谢。
答案 0 :(得分:16)
你可以使用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
答案 1 :(得分:9)
您可以使用数据库。创建一个单独的表“设置”,用于存储所需的键/值参数。此解决方案的缺点是性能损失(每次需要设置时查询DB)。要解决此问题,您可以通过“cache_money”等缓存读取/写入,或使用“Rails.cache”创建自己的缓存
答案 2 :(得分:4)
试着看看它可能就是你所需要的。
答案 3 :(得分:1)
最好的方法是使用数据库表。每行应包含关键字和值。 Simples。
答案 4 :(得分:1)
我自己使用了app_config gem一段时间了,但是使用rails 2.3.9(也可能还有rails 3.x)失败了,所以我发现this blog提到{{3} }和rails-settings,rails-settings在DB中存储值,但配置内置了命名空间。我没试过,但我想我会切换到rails-settings。
我现在注意到configuration似乎比其他the branch of rails-settings that Yi-Ru Lin mentions
更有特色首领
答案 5 :(得分:1)
对于rails 4,如果您使用的是postgresql,则可以使用HStore,这就像一个可序列化的属性,但您可以使用它进行SQL查询。
对于rails 3,您可以使用activerecord-postgres-hstore gem。
答案 6 :(得分:-1)
我尝试了class,但它没有按照描述的那样工作。显然作者忘了在gem使用说明中提到一些额外的调整。我没有为设置操作编写控制器。
相反,我成功地利用了https://github.com/huacnlee/rails-settings-cached - 尽管存在一些小问题,但这个宝石比rails-settings-cached
更合理。
configurable_engine
gem有一个缺点:它具有模糊且不方便的硬编码路径。宝石的作者https://github.com/paulca/configurable_engine,但表示他目前没有时间。
因此,只需创建自己的路线即可轻松解决此问题。这是我的代码(为使这个宝石真正起作用而添加):
<强>的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 强>
<h1 class="page-header">Settings</h1>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @configurables.each do |configurable| %>
<tr>
<% if configurable.try(:name) %>
<td><%= Configurable.defaults[configurable.name][:name]%></td>
<td></td>
<td><%= link_to 'Show', [:admin, configurable] %></td>
<td><%= link_to 'Edit', edit_admin_configurable_path(configurable) %></td>
<td><%= link_to 'Destroy', [:admin, configurable], method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% else %>
<td><%= Configurable.defaults[configurable][:name] %></td>
<td><%= link_to 'Create', new_admin_configurable_path(name: configurable) %></td>
<td colspan="3"></td>
<% end %>
</tr>
<% end %>
</tbody>
</table>
</div>
<强> edit.html.erb 强>
<h1>Editing <%= @new ? "new " : "" %>setting</h1>
<%= render 'form', configurable: @configurable %>
<%= link_to 'Show', [:admin, @configurable] %> |
<%= link_to 'Back', admin_configurables_path %>
<强> show.html.erb 强>
<p>
<strong>Name:</strong>
<%= Configurable.defaults[@configurable.name][:name] %>
</p>
<p>
<strong>Value:</strong>
<%= @configurable.value %>
</p>
<%= link_to 'Edit', edit_admin_configurable_path(@configurable) %> |
<%= link_to 'Back', admin_configurables_path %>
<强> _form.html.erb 强>
<%= form_for([:admin, configurable]) do |f| %>
<div class="field">
<%= f.label "Name" %>
<%= Configurable.defaults[@configurable.name][:name] %>
</div>
<div class="field">
<%= f.label "Value" %>
<%= f.text_area :value %>
</div>
<div class="actions">
<%= f.submit "Submit" %>
</div>
<% end %>
由于硬编码路由,我的控制器并不完全符合REST,但它非常接近。我的new
操作实际上创建了一个(数据库存储的)设置(仅覆盖其yml文件值)。
因此,添加到gem描述代码的代码可以让您实际使用运行时可更改的RoR设置。
gem需要您事先在yml文件中设置一些默认值,稍后您可以在运行时覆盖它们。但是你不能在运行时创建一个新的设置(not-yml-file-existent) - 只修改一个存在的(在yml文件中) - 这是非常合乎逻辑的。
或者您可以恢复(在运行时)任何设置的默认值(通过删除其数据库存储的覆盖值)。
检查此代码以使用Rails 5。