Posted at

fields_for内のf.collection_selectとactive_hashを表示させる

こんにちは!

ビューのマークアップ中に学んだ内容を備忘録として


実装方法


開発環境

Ruby 2.5.1

Rails 5.2.3


参考


Railsウィザード形式フォームで新規登録~Devise+session~

https://qiita.com/ATORA1992/items/40fc543742a6df5a17c1

Railsのgem 'active_hash'で都道府県データを作成したみた

https://kossy-web-engineer.hatenablog.com/entry/2019/01/08/205702

Github active_hash

https://kossy-web-engineer.hatenablog.com/entry/2019/01/08/205702



やりたい事


  • active_hashで実装した都道府県データをセレクトボックスを使ってビューに表示する

  • セレクトボックスのデフォルト矢印をFontAwesomeでナイスな矢印に変える


事前準備


  • field_forを扱えるようにmodel/controller/routesの実装を完了させる

  • 都道府県データをモデルを介さず扱えるようにする為にgem 'active_hash'を導入する

  • modelを自作し都道府県の元データを作成する


↑↑チームメンバーが実装してくれたのでこの記事では割愛


セレクトボックスをビューに表示させる


完成

住所の都道府県選択するボックスがあって、

スクリーンショット 2019-08-27 16.05.06.png

プルダウンさせると、

スクリーンショット 2019-08-27 16.06.43.png

って感じです


コード

:prefecture.html.haml

%body.new-member-registration-body
%main.new-member-registration-body__main
%section
.new-member-registration__title 発送元・お届け先入力
= form_for @user, url: signup_index_path, method: :post, html: { class: 'registration-form' } do |f|
= f.fields_for :deliver_adress do |d|
.new-member-registration-form-content
.new-member-registration-form-content__group
= f.label :都道府県, { class: 'new-registration-label' }
= f.label :必須, { class: 'form-require' }
.prefecture-select-wrap
= d.collection_select :prefecture, Prefecture.all, :id, :name

colleciton_selectはform_for,form_tagにて使用可能

引数については、

(プロパティ名,オブジェクトの配列,value属性の項目,テキストの項目[,オプション])

value属性にはid: 1 ~ id: 47、テキストの項目にはname: '北海道 ~ name: 沖縄'キー: バリュー形式にてmodels/prefecture.rbには実装されているのでPrefecture.allで都道府県データを全て引っ張ってきます


cssでレイアウトを整える


prefecture.scss

#user_deliver_adress_attributes_prefecture {

height: 32px;//箱の高さ
width: 300px;//箱の横幅
padding: 10px 16px 8px;//select_box内の文字を適切な位置へ
margin-top: 8px;//箱の上部に余白を与える
border-radius: 4px;//箱の角を滑らかに
border: 1px solid #ccc;//箱の線のスタイル
background-color: #fff;//箱の背景色
font-size: 16px;//文字の大きさ
}

このidはcollection_selectに自動で付与されるidです

最初、クラス名を与えていたのですが、

= d.collection_select :prefecture, Prefecture.all, :id, :name, class: 'クラス名'って書いてもcssが反映されないんですよね...なぜだろう?と調べてみると、第三引数にclass名は持ってこれないみたいですね。Railsドキュメントのソースコードに書いています


メソッドの定義

def select(method, choices = nil, options = {}, html_options = {}, &block)


第三引数は空ハッシュでoptionをスキップしてあげる必要があります。= d.collection_select :prefecture, Prefecture.all, :id, :name, {}, class: 'クラス名'これでクラスを与える事ができます。

が、id持っているのにわざわざクラスを付与しなくても良いと思い、id = user_deliver_adress_attributes_prefectureへcssを当てました


FontAwesomeで矢印をナイスに

このデフォルト矢印を、

スクリーンショット 2019-08-27 17.11.08.png

FontAwesomeを使って、

スクリーンショット 2019-08-27 17.10.07.png

へ変更します


prefecture.html.haml

.prefecture-select-wrap

= d.collection_select :prefecture, Prefecture.all, :id, :name
%i.prefecture.fas.fa-chevron-down

hamlさんは親要素.prefecture-select-wrapに対して= d.collection_select :prefecture, Prefecture.all, :id, :name%i.prefecture.fas.fa-chevron-downを子要素として並列にしてあげないとうまくいかなかったです


prefecture.scss

#user_deliver_adress_attributes_prefecture {

height: 32px;
width: 300px;
padding: 10px 16px 8px;
margin-top: 8px;
border-radius: 4px;
border: 1px solid #ccc;
background-color: #fff;
line-height: 1.5;
font-size: 16px;
-webkit-appearance: none;//追加:デフォルト矢印を消す
}
.prefecture-select-wrap {
position: relative;//親のポジション指定
}
.prefecture.fas.fa-chevron-down {
position: absolute;//子のポジション指定
right: 25px;//右25px空ける
top: 60%;//上から60%の位置へ
z-index: 2;//親の下へ潜り揉まないようにする
color: #888;
transform: translate(0, -50%);//translate(X方向の移動距離, Y方向の移動距離)
font-size: 18px;
}


transform: translate(0, 50%)はHTMLリファレンスを参考にしましたがあまり理解できていないです。


transform …… 要素に2D変形、または、3D変形を適用する

http://www.htmq.com/css3/transform.shtml


このプロパティ設定がないと矢印が意図したレイアウトになってくれなさそう


まとめ

今回はフロントのマークアップで自分が躓いた部分を記事にまとめて見ました。

本当はactive_hashfields_forの実装部分もアウトプットできれば良いのだが、いかんせんちゃんと理解ができていないです。やはり自分の力で実装しないと理解はできないと痛感しています。個人アプリを作る時は自力で実装するのでその時にまたQittaに記事書きます。


最後に


筆者について

TEXH::EXPERT渋谷校の夜間クラスで4月からRuby・Railsの学習をしています。

記載内容に不備・不足があればご指摘いただけると幸いです。

至らぬ点ばかりですので、改善点がありましたらどんどんご指摘下さい!