gem enum_helpを使用し、enum値のi18n化と権限のプルダウンを実装

前提

enumとransackは導入済み
enum
ransack

実装内容

enumで定義した値の翻訳
ユーザー一覧画面でのプルダウン検索
f:id:meo2:20210712031757p:plain:w500:h200

導入

gem 'enum_help'

bundle install

enumの設定

  • general・・・一般
  • admin・・・管理者 と定義する。
  enum role: { general: 0, admin: 1 }

i18nの設定

 enums:
   user:
     role:
       general: '一般'
       admin: '管理者'  

view

viewで以下のように記述することで呼び出せる。

<%= user.role_i18n %>

プルダウンの実装

controller

  def index
    @q = User.ransack(params[:q])
    @users = @q.result(distinct: true).page(params[:page])
  end

params[:q]で検索フォームに入力した文字を取得(viewから送られてきたパラメータ)デフォルトで:qとなっている。→インスタンス変数@qを定義。
ransackメソッド、送られてきたパラメータをもとにテーブルからデータを検索。
resultメソッドでransackメソッドで取得したデータをオブジェクトに変換し、検索結果を渡す。
distinct: trueで重複を防ぐ
pageメソッドでページネーションの実装。

view

  <%= search_form_for @q, url: admin_users_path do |f| %>
    <div class="row">
        <div class="form-inline align-items-center mx-auto">
            <div class="col-auto">
              <%= f.search_field :first_name_or_last_name_cont, placeholder:'検索ワード', class:'form-control' %>
            </div>
            <div class="col-auto">
              <%= f.select :role_eq, User.roles_i18n.invert.map { |key, value| [key, User.roles[value]]}, include_blank:'指定なし', class:'form-control mr-1' %>
            </div>
            <div class="col-auto">
              <%= f.submit '検索', class:'btn btn-primary' %>
            </div>
        </div>
    </div>
<% end %>

search_form_forメソッドはransackで用意されているメソッド
form_withやform_forと同じ
検索オブジェクトqを指定。
urlオプションでリクエストするurlを渡す。→renderでパーシャルを読み込む時に指定。

<%= f.select :role_eq, 
User.roles_i18n.invert.map { |key, value| [key, User.roles[value]]}, 
include_blank:'指定なし', #第3引数 
class:'form-control mr-1' %> #第4引数,htmlオプション

について
role_eq、eq(equals)は ransackのメソッド、等しい値を持つレコードを返す。
invertメソッドでkeyとvalueを入れ替える
mapメソッド配列.map {|変数名| 具体的な処理 }で戻り値を配列へ返す。
include_blankオプションは先頭に表示されるメッセージに空白行を表示する。

f.select

f.selectを使うと、セレクトボックスの選択項目や選択された時の値や、セレクトボックスに設定したいオプションを指定できる。

<%= f.select :保存されるカラム名, [ ["表示される文字","保存される値"], {オプション}, {htmlオプション} ] %>

User.rolesでuserモデルのroleの値(ハッシュ)を取得
{キー1 => 値1, キー2 => 値…}

pry(main)> User.roles
=> {"general"=>0, "admin"=>1}

enum_helpの導入により、User.roles_i18nというメソッドを使えるようになる。
i18nで設定した日本語を適用

pry(main)> User.roles_i18n
=> {"general"=>"一般", "admin"=>"管理者"}

invertメソッドでハッシュのkeyとvalueを入れ替える。
f.select :保存されるカラム名, [ ["表示される文字","保存される値"]に合わせたいので、ハッシュを入れ替える。
こうすることで、プルダウンが英語→日本語に切り替わる。

pry(main)> User.roles_i18n.invert
=> {"一般"=>"general", "管理者"=>"admin"}

mapメソッドでハッシュを配列にする。
一般、 管理者というキーをkey に、general 、adminという値が valueへ代入。

pry(main)> User.roles_i18n.invert.map { |key, value| [key, User.roles[value]]}
=> [["一般", 0], ["管理者", 1]]

ransackはenumで定義したstringに対応していないので、integerにする必要がある。
[key, User.roles[value]]valueをintegerにしている。

pry(main)> User.roles['general']
=> 0
pry(main)> User.roles['admin']
=> 1