🐰

Rails で不変の定数を定義する

2024/02/16に公開

Rails で定数を使いたかったので、作法的なものを調べていたところ、書き換えを防止する機能を見つけたので備忘録として残します。

そもそもの定数の使い方

  1. config gem を利用して yml で管理する
  2. /config/application.rb とか /config/environments/*.rb とかで管理する
  3. /config/initializer/constants.rb を新規に作成して module を定義する

他にもモデル・コントローラーでしか利用しない場合は application_controller.rb などで定義するなどの方法があります。
今回は、関数も同時に管理したかったので3の方法を使うことにしました。

/config/initializer/constants.rb を新規に作成して module を定義する

# /config/initializers/constant_parameters.rb
module ConstantParameters 
    AUTHOR = "ndj"
end

呼び出し方の例

# /app/controllers/soregashi_controller.rb
class SoregashiController < ApplicationController

  def author
    render json: {message: "author is #{ConstantParameters.AUTHOR}"}, status: :ok
  end
end

不変化には freeze を使う

freeze メソッドは Object クラスのインスタンスメソッドです。
freeze されたオブジェクトに対して破壊的な変更を加えようとすると FrozenError の例外を発生します。

constant_parameters.rb で freeze をしておく

# /config/initializers/constant_parameters.rb
module ConstantParameters 
    AUTHOR = "ndj"
end

ConstantParameters.freeze

エラーが発生することを確認する
下記コードは FrozenError を発生することが確認できます。

# /app/controllers/soregashi_controller.rb
class SoregashiController < ApplicationController

  def author
    ConstantParameters.AUTHOR = "ndjndj" # ここでエラーが発生する。
    render json: {message: "author is #{ConstantParameters.AUTHOR}"}, status: :ok
  end
end

さいごに

エラーが発生するなら事前に意図せず変更してしまうことがなさそうなので安心ですね。

自分の中では定数といえば UPPER_SNAKE_CASE で管理するイメージしかなかったのです[1]が、いろいろな仕組みを知ることができました。利用用途によって使い分けたいです。

参考

https://docs.ruby-lang.org/ja/latest/method/Object/i/freeze.html
https://qiita.com/takeda-no-nao/items/415107d737c2f35bb244
https://takeda-no-nao.net/programming/ruby/how-to-define-constants/
http://mindia.jp/akikumo_tea/rails-定数

脚注
  1. Dart の文脈で SCREAMING_CAPS って聞いたことあるけど、Dart 特有の呼び方なのかな?確かに叫んでるっぽいなと思った記憶がある。他にも snake_case は蛇みたいだし CamelCase はラクダみたいだし、kebab-case で急に加工品になるのも面白い。 ↩︎

GitHubで編集を提案

Discussion