はじめに
どうも、もきおです。RailsでModelに定義した定数をControllerやViewで使用する場面が実務でちょくちょく使う事があり、どうやって参照するんだっけ?と思ったので、調べたのをメモとして残しておきたいと思います。
結論
定数を参照するにはModel名(Rubyならクラス名)::定数名で参照する事ができます。
MAIN_USERS = ["Bob", "Keny", "John", "July", "Karen"].freeze
User::MAIN_USERS
# => ["Bob", "Keny", "John", "July", "Karen"]
具体例
さて、具体例に入っていきましょう。今回はユーザー登録の際、SNSのURLを入力する欄があるとします。その際、省きたいURLを予め定数として登録しておき、実際入力され渡ってきたURLと定義していた定数が部分一致する場合、バリデーションでアラートを表示するというパターンで記述したいと思います。
まずは良く使うものをmodelに定数定義しましょう。.freeze
メソッドで変更不可にしています。
SNS_URLS = ["youtube.com", "twitter.com", "instagram.com", "tiktok.com"].freeze
そしてcontrollerで条件分岐を書いていきます。viewでも書き方は一緒です。
if User::SNS_URLS.any?{ |url| params.require(:user)["url"].include?(url) }
flash.now[:alert] = "SNSのURLを再度確認してください。"
end
条件分岐部分が少し複雑ですが、入力されたURL(params.require(:user)["url"]
)を定数のURLそれぞれと一つずつ部分一致しているか確認。
.any?
は一致したものがあった時点でtrueを返すメソッドなので部分一致するURLが見つかった時点でtrue判定になりアラートが表示されるという感じです。
ついでに分解して解説しておくと{ |url| params.require(:user)["url"].include?(url) }
の部分をブロックで書いてますが、これはループ処理を簡略化して記述しています。
簡略化しないと以下みたいな感じ
# ["youtube.com", "twitter.com", "instagram.com", "tiktok.com"].each do |url|
User::SNS_URLS.each do |url|
if params.require(:user)["url"].include?(url)
flash.now[:alert] = "SNSのURLを再度確認してください。"
end
end
あとがき
意外と書き方が想像できなくて当時調べるまで参照の仕方は検討がつきませんでした笑
メモとして将来の自分の役に立つかな?笑
最後までご覧いただき本当にありがとうございました!!
Twitterでも日頃の業務で思ったことを呟いていくのでご覧いただけると幸いです。
@mokio_50