rails_admin と devise を導入したプロジェクトで、root_path と rails_admin_path が異なる場合のログアウト遷移先設定方法
前提
rails_admin
devise
困っていたこと
一般向けサイトと管理サイトを作成し、管理サイトのみ devise でログイン処理を作成しました。
プロジェクト自体の root_path は一般向けサイトを指定したのですが、そうすると、管理サイトからログアウトした際に root_path に遷移してしまい、非常に不便でした。
対応方法
結論から言うと、application_controller.rb
にメソッドを追加しました。
def after_sign_out_path_for(resource) rails_admin_path end
これでログアウトしたら rails_admin_path に遷移するようにできます。
rails_admin 側に設定が存在するだろうと考えて調べていたため、devise 側だということに気づくのに時間がかかってしまった。。。
複数選択可能なチェックボックスやリストボックスで選択された内容を一つのカラムに保存する方法
前提
どういう場面で使うか
入力画面で複数チェックボックスやリストボックスを表示するのは以下のようにかけます。(例としてリストボックス)
= m.select :answer, [['ア', 'ア'], ['イ', 'イ'], ['ウ', 'ウ'], ['エ', 'エ']], {}, { multiple: true, size: 4 }
このようにして作成したリストボックスで、以下のようにセットすると、controller には以下のように配列で返却されます。
# 'ア'と'ウ'を選択した場合 "answer" => [ [0] "", [1] "ア", [2] "ウ" ]
これには問題点があります。
- そのままではカラムに入らないこと
- 最初に空の値が存在すること
対処方法
そこで、以下のように array のメソッドである、 delete
を使って空の値を削除し、 join
を使ってカンマ区切りで結合します。
params[:questionnaire][:answer].delete('') params[:questionnaire][:answer] = params[:questionnaire][:answer].join(',')
上記を行うことで、返却値は
# 'ア'と'ウ'を選択した場合 "answer" => "ア,ウ"
となり、1カラムに格納することができるようになります。
データベースに格納した後に、その値を配列に戻して、画面に再表示しなければならないような場合はだんだんつらくなると思いますが、格納するだけでOKな場合はこのようなやり方はありだと思います。
rails_admin 導入時の 管理サイトタイトル変更方法
rails_admin を導入してカスタマイズ
rails アプリケーションを作成していて、管理サイトがほしい、と言われることが結構あります。
あんまりこだわりがないお客様の場合、rails_admin を導入することが多いです。
rails で良く利用されている管理画面の gem は他にもありますが、導入が簡単なんですよね。
で、導入した後に毎回躓くのがこれ。
サイトタイトルってどうやって変更する?
通常通りに導入すると、サイトのタイトルがrails アプリケーション名になってしまうんですよね。
rails アプリケーション名は英語ですので、日本語化が必要になるんです。
で、どうすればいいかというと
# ./config/initializers/rails_admin.rb config.main_app_name = %w(〇〇システム 管理サイト)
と、rails_admin の config に記載すればいいです。
毎回忘れて、過去に作ったアプリを見て思い出すので、ブログに書いておきます。
simple_form を利用している時にsubmit ボタンにボタン名と value をセットする方法
前提
導入gem
- simple_form
- haml
普通の書き方だと、ボタン名が value の値になってしまう
通常、submit ボタンは以下のように記載すると思います。
= f.button :submit, 'ボタン名' { name: "#{f.object_name}[completed]", value: '1', class: 'btn btn-primary' }
しかし、この状態で実際に動作させてみると、ボタン名には value に指定した"1" が表示されてしまいます。
simple_form では、通常ボタン名が value にセットされますが、 value がセットされている場合はボタン名が反映されないためです。
こうすればうまくいく
では、どうすればいいのかというと、以下のように submit を指定せず、button を指定し、 do を付けてボタン名を入れ子にするとうまくいきます。
= f.button :button, { name: 'test', value: '1', class: 'btn btn-primary' } do ボタン名
simple_form 手強い...
simple_form を利用していない場合はハマらないと思うんですが、simple_form を導入していると最終的な html の出力が simple_form 次第になるので、ハマってしまった時に解決させるまでには試行錯誤が必要になることが多いです。。
simple_form と bootstrap を利用した環境で f.collection_select をどう書くか
前提
rails 4系
simple_form 3.2.1
bootstrap-sass 3.3.7
そのままだと(非bootstrap になる)
通常、collection_selectは以下のように記載しています。
= f.collection_select :option_id, OptionMaster.all, :id, :option_name, { prompt: true, class: 'form-control' }
しかし、これだと以下の画像のように、非bootstrapな表示をされてしまいます。
bootstrap に対応した書き方
下のように記載することで、bootstrapに対応した表示になります。
= f.input :option_master_id, collection: OptionMaster.all.map { |v| [v.option_name, v.id] }
f.input とした上で、collection: の後ろに配列で value と text の組を記載するのがポイントです。
公式も確認したのですが、いまいち曖昧に読み取れたので、ブログに書いてみました。
ActiveRecord から取得した1レコードから配列を作成する
例として、option_mastersというテーブルが存在していた場合
# # Table name: option_masters # # id :integer not null, primary key # option_name :string # option1 :string # option2 :string # option3 :string # option4 :string # option5 :string # option6 :string # option7 :string # option8 :string # option9 :string # option10 :string # operator :string # created_at :datetime not null # updated_at :datetime not null #
このテーブルに登録されているはじめの1レコードを取得し、配列化したい場合は
OptionMaster.first.attributes.values
とすることで取得できます。
これはattributes
でレコードをハッシュとして取得することができ、values
でハッシュの値を配列として取得することができるためです。
今回は更に、テーブルに登録されているはじめの1レコードを取得し、option1~10 を取得したいとなりました。("option_name"や"operator"は値として必要なかった)
その場合、以下のように記載することで、目的を達することができました。
OptionMaster.first.attributes.select { |k, v| k =~ /option\d/ && v.present? }.values
これは、select
で条件に合致したキーの値だけを取得するためにk =~ /option\d/
でキーに対して正規表現で記載しています。
更に、値が入っていない場合は必要なかったので、v.present?
で除外しています。
まだまだこういったことがすぐにできるほど Ruby のメソッドを知らないので、作業速度が遅いですが、調べるたびに Ruby は書きやすいなぁと感じます。