LoginSignup
1
5

More than 3 years have passed since last update.

メモ:Railsでサイト設定情報をDBに持たせて柔軟に運用する

Last updated at Posted at 2019-09-19

この記事は

  • RailsでDBにサイト設定情報を持たせて画面から設定させたかったです
  • ここでいうサイト設定というのは、例えばサイトのタイトルみたいな、あとからちょくちょく変えたくなるようなアプリケーションレイヤの設定項目です
  • 設定ファイルに記述する方式でよければrails configとか使えばいいのですが、スピードと分業の都合でリアルタイムに画面から変更したかったです

対応方針

rails-settings-cached gem

  • rails-settings-cachedというgemを使ってやってみました
  • このgem、元々はrails-settingsのforkらしいのですが、跡形もないくらいにいじられているので、完全に別物と思ってください

このgemのいいところ

DB構成が手軽

  • まずDBにデータを保存するという基本的な構成が想定通りです
  • かつ、保持させたい設定情報がキーバリュー方式の2つのカラムで管理されていて手軽です
  • 対する方式としては、設定項目ごとにカラムを追加するというやりかたもありますが、これだと、設定項目が増える度につどつどmigrationが入ってめんどくさいです

性能について考えられている

  • それから、性能を改善するために、RequestStoreにデータを入れて再利用しています
    • Railsのリクエスト開始時に最新の設定情報を取りに行って、同一リクエスト内では同じものを使い回す
    • リクエスト終了時に設定情報を破棄する
  • RequestStoreを利用しているおかげで、呼び出すたびにDBアクセスはしないですんでおり、ある程度SQL発行回数を抑制しつつ、複数APサーバでも動的な設定情報変更が反映できる構成になっています
  • 多分gem名のcachedというのはここの部分を指していると思います。

導入手順

gemのインストール

  • gemを普通に入れます
Gemfile
gem "rails-settings-cached", "~> 2.0"

DBテーブルの追加

rakeが・・・

  • テーブル追加したりモデルクラスを追加するrakeが付いているのですが、なぜかエラーが出て使えませんでした
  • なので、ソースのtemplateを参考に下記のようなクラスを作りました
    • sample_configs/SampleConfig というなまえのテーブル/モデルを作るものとします

テーブル定義

  • 今みてるRailsアプリケーションがRidgepoleを使っているので、下記のように定義しました。
  • rails標準のmigrationでも同じような事を書けば大丈夫だと思います
Schemafile
create_table :sample_configs, id: :integer, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" do |t|
  t.string :var, null: false
  t.text :value, null: true
  t.timestamps

  t.index :var, name: 'index_sample_configs_var', unique: true
end

モデル定義

  • こんな感じに定義します
  • ポイントはfieldに定義するときにハードコードでデフォルト値を設定できるというところです
  • DBに値がなかった場合は自動的にこちらを参照してくれるので、運用によっては結構便利だと思います。
app/models/sample_config.rb
# RailsSettings Model
class SampleConfig < RailsSettings::Base
    self.table_name = 'sample_configs'
    cache_prefix { "v1" }

    # Define your fields
    # field :host, type: :string, default: "http://localhost:3000"
    # field :default_locale, default: "en", type: :string
    # field :confirmable_enable, default: "0", type: :boolean
    # field :admin_emails, default: "admin@rubyonrails.org", type: :array
    # field :omniauth_google_client_id, default: (ENV["OMNIAUTH_GOOGLE_CLIENT_ID"] || ""), type: :string, readonly: true
    # field :omniauth_google_client_secret, default: (ENV["OMNIAUTH_GOOGLE_CLIENT_SECRET"] || ""), type: :string, readonly: true

    field :example1, type: :text, default: "hello!"
end

使い方

  • こんな感じで普通に使えます
  • field定義するときに指定した型に応じて適当にキャストされて返ってくるのもなかなか便利です
some_controler.rb
def some_action
  render text: SampleConfig.example1
end
  • ちなみに値を代入するだけでsaveせずともDBが更新されてしまうのでそこだけは注意してください
  • モンキーパッチで潰しておいた方がいいかも

ActiveAdminの利用

  • わざわざDBに値を保持させたので、画面から更新したくなると思います
  • まあまあよく使われているActiveAdminを利用して、普通にこれらの値を画面から更新することができます
  • 下記ファイルを作成すれば、普通に画面からCRUDでメンテできるようになります
app/admin/sample_configs.rb
ActiveAdmin.register SampleConfig do
    permit_params :var, :value
end

終わりに

  • 全然有名じゃないgemな気がしますが、結構いい感じだなとおもいました
1
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
5