2010-01-24 36 views
17

Tôi có ứng dụng Rails tương đối đơn giản và tôi muốn lưu trữ các cài đặt cấu hình khác nhau mà người dùng quản trị có thể thay đổi trong khi ứng dụng đang chạy, ví dụ như cho phép nhận xét trên bài đăng hoặc thay đổi định dạng hiển thị cuộc hẹn.Ruby on Rails - Lưu trữ cấu hình ứng dụng

Tôi biết tôi có thể lưu trữ các hằng số, vv trong tệp environment.rb, tuy nhiên chúng dường như chỉ được tải khi máy chủ được khởi động lại.

Có một địa điểm thay thế nào để tôi có thể xác định thông tin này hoặc tốt hơn nên giữ nó trong cơ sở dữ liệu không?

Bất kỳ lời khuyên nào được đánh giá cao.

Cảm ơn.

Trả lời

9

Bạn có thể sử dụng cơ sở dữ liệu. Tạo bảng "cài đặt" riêng biệt để lưu trữ các thông số khóa/giá trị bạn cần. Nhược điểm của giải pháp này là một hit hiệu suất (truy vấn DB mỗi khi bạn cần một thiết lập). Để khắc phục sự cố này, bạn có thể đọc/ghi thông qua bộ nhớ cache như "cache_money" hoặc tạo bộ nhớ cache của riêng bạn bằng cách sử dụng "Rails.cache"

+0

Chỉ cần đăng câu trả lời bằng cách tiếp cận giữ các cài đặt trong cơ sở dữ liệu, cập nhật chúng khi cần và không bị các vấn đề về hiệu năng mà không cần phải lưu vào bộ nhớ đệm DB. – silverdr

1

Cách tốt nhất là sử dụng bảng cơ sở dữ liệu. Mỗi hàng phải chứa một từ khóa và một giá trị. Các mẫu.

+0

OK, nhưng làm cách nào bạn quản lý các loại dữ liệu khác nhau? Ví dụ: Ví dụ, một số cài đặt sẽ là boolean, các chuỗi khác, các số khác sẽ là số nguyên. – Dan

+3

lưu chuỗi JSON. – Luke

+0

Bạn có thể không chỉ sử dụng một hàng và thêm từng cài đặt dưới dạng cột không? Việc truy xuất một cài đặt sau đó sẽ đơn giản như SELECT enable_setting FROM server_settings LIMIT 1; – Edward

4

Hãy thử xem nó có thể là những gì bạn cần.

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

+4

Các repo vắt là 4 năm trong ngày và không thể sử dụng với đường ray hiện đại. Đá quý ledermann yêu cầu bạn buộc vào một đối tượng bản ghi hoạt động khác (làm cho nó không thể sử dụng cho các cài đặt ứng dụng toàn cầu.) Nếu bạn muốn cài đặt ứng dụng toàn cầu, https://github.com/huacnlee/rails-settings-cached là tốt nhất – portforwardpodcast

1

Tôi đã sử dụng app_config đá quý trong một thời gian bản thân mình, nhưng nó không thành công với đường ray 2.3.9 (và có lẽ cũng với đường ray 3.x), vì vậy tôi tìm thấy this blog đề cập đến rails-settingsconfiguration, rails- cài đặt lưu trữ các giá trị trong DB, nhưng cấu hình có các không gian tên được tích hợp sẵn. Tôi đã không thử chúng, nhưng tôi nghĩ rằng tôi sẽ chuyển sang thiết lập đường ray.

tôi nhận thấy bây giờ mà the branch of rails-settings that Yi-Ru Lin mentions có vẻ là hơn featureful hơn người kia rails-settings

Jarl

15

Bạn có thể sử dụng đá quý rails-settings-cached mà là một ngã ba của đường ray-settings đá quý (được liên kết bởi Yi-Ru Lin trong một câu trả lời khác).

Sau khi cài đặt, bạn sẽ có thể làm những việc như:

Setting.foo = 123 
Setting.foo # returns 123 

Bạn cũng có thể quản lý cài đặt trên các mô hình, ví dụ:

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

Đối với đường ray 4, nếu bạn đang sử dụng postgresql, bạn có thể sử dụng HStore, giống như một thuộc tính có thể tuần tự hóa, nhưng bạn thực hiện các truy vấn SQL với nó.

Đối với đường ray 3, bạn có thể sử dụng đá quý activerecord-postgres-hstore.

0

Tôi đã thử https://github.com/huacnlee/rails-settings-cached, nhưng nó không hoạt động như được mô tả. Rõ ràng là tác giả quên đề cập đến một số điều chỉnh bổ sung trong mô tả sử dụng đá quý. Tôi không thể viết một bộ điều khiển cho thao tác cài đặt.

Thay vào đó tôi đã thành công để sử dụng https://github.com/paulca/configurable_engine - mặc dù một số vấn đề nhỏ, đá quý này là hợp lý hơn nhiều so với rails-settings-cached.

Đá quý configurable_engine có một nhược điểm: nó có các tuyến đường được mã hóa cứng không rõ ràng và không thuận tiện. Tác giả của đá quý promised to correct it, nhưng nói rằng ông hiện không có thời gian cho nó.

Vì vậy, vấn đề này đã được sắp xếp dễ dàng bằng cách đơn giản tạo tuyến đường của riêng tôi. Đây là mã của tôi (thêm vào làm cho viên ngọc này thực sự làm việc):

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 %> 

Do mã hóa cứng các tuyến điều khiển của tôi không hoàn toàn tuân thủ REST, b ut nó khá gần. Hành động new của tôi thực sự tạo cài đặt (được lưu trữ cơ sở dữ liệu) (chỉ để ghi đè giá trị tệp yml của nó).

Vì vậy, mã này được thêm vào mã mô tả đá quý cho phép bạn thực tế sử dụng cài đặt RoR có thể thay đổi theo thời gian chạy.

Đá quý yêu cầu bạn đặt một số giá trị mặc định trong tệp yml trước, bạn có thể ghi đè lên sau này tại thời gian chạy. Nhưng bạn không thể tạo một thiết lập mới tại thời gian chạy (không-yml-file-existent) - chỉ sửa đổi một tệp tồn tại (trong tệp yml) - điều này khá hợp lý.

Hoặc bạn có thể khôi phục (tại thời gian chạy) giá trị mặc định của bất kỳ cài đặt nào (bằng cách xóa giá trị ghi đè được lưu trữ cơ sở dữ liệu của nó).

Mã này đã được kiểm tra để hoạt động với Rails 5.

Các vấn đề liên quan