簡體   English   中英

Ruby on Rails-存儲應用程序配置

[英]Ruby on Rails - Storing application configuration

我有一個相對簡單的Rails應用程序,我想存儲管理員可以在應用程序運行時更改的各種配置設置,例如,允許對帖子發表評論或更改日期的顯示格式。

我知道我可以將常量等存儲在environment.rb文件中,但是這些常量似乎僅在服務器重新啟動時才加載。

有沒有其他地方可以定義此信息,還是最好將其保存在數據庫中?

任何建議表示贊賞。

謝謝。

您可以使用rails-settings-cached的 gem,它是rails-settings寶石的一個分支(在另一個答案中,由Yi-Ru Lin鏈接)。

設置完成后,您將可以執行以下操作:

Setting.foo = 123
Setting.foo # returns 123

您還可以管理模型的設置,例如:

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

您可以使用數據庫。 創建一個單獨的表“設置”,用於存儲所需的鍵/值參數。 該解決方案的缺點是性能下降(每次需要設置時都會查詢數據庫)。 要解決此問題,您可以通過“ cache_money”之類的緩存進行讀/寫操作,也可以使用“ Rails.cache”創建自己的緩存

嘗試查看它可能是您所需要的。

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

最好的方法是使用數據庫表。 每行應包含一個關鍵字和一個值。 簡單。

對於rails 4,如果您使用的是postgresql,則可以使用HStore ,它類似於可序列化的屬性,但是您可以使用它進行SQL查詢。

對於rails 3,可以使用activerecord-postgres-hstore gem。

我本人已經使用app_config gem有一段時間了,但是它在Rails 2.3.9(可能還與Rails 3.x)上失敗了,所以我發現這個博客提到了rails-settingsconfiguration ,rails-settings將值存儲在DB中,但是配置具有內置的名稱空間。 我沒有嘗試過,但是我想我會切換到Rails-settings。

我現在注意到, 林逸如提到的rails-settings分支似乎比其他rails-settings更具特色。

貴族

我嘗試了https://github.com/huacnlee/rails-settings-cached ,但是它不能像描述的那樣工作。 顯然,作者忘記了在寶石用法說明中提到的其他一些改進。 我未能編寫用於設置操作的控制器。

相反,我成功地使用了https://github.com/paulca/configurable_engine-盡管存在一些小問題,但該gem遠比rails-settings-cached更合理。

configurable_engine gem有一個缺點:它具有難以理解且不方便的硬編碼路由。 寶石的作者答應予以糾正 ,但他說他目前沒有時間。

因此,只需創建我自己的路線即可輕松解決此問題。 這是我的代碼(為了使這個寶石真正起作用而添加了):

routes.rb

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

admin / 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文件中預先設置一些默認值,稍后可以在運行時覆蓋它們。 但是您不能在運行時創建新設置(不存在yml文件)-僅修改存在(在yml文件中)的設置-這是很合邏輯的。

或者,您可以(在運行時)恢復任何設置的默認值(通過刪除其數據庫存儲的替代值)。

該代碼已經過檢查,可以與Rails 5一起使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM