Rails基礎22
今回は日付ごとじゃなくカリキュラムの単元単位でスクラップを作成してみる。両方試してどっちがいいか考えよう。
2023.10.12
まずは忘れずにブランチを切る!
課題の概要把握。今回は新要素は少なくて、今までやったことの応用でできることが多そうだ。
ただ、アクティブ・非アクティブというのが何を指してるのかいまいちわかってない。
まずは実際の操作を一通りなぞってみる。
ユーザー詳細および編集
- メニューから「ユーザー一覧」へ
- 「詳細」ボタンをクリックして「ユーザー詳細」へ
- 「ユーザー詳細」内の編集ボタンから「ユーザー編集」へ
- 必要事項を入力してユーザー情報を更新、「ユーザー詳細」へリダイレクト
ユーザー削除
- 「ユーザー一覧」内の削除ボタンをクリック
- アラートが出るのでOKをクリック
- 削除されたユーザーが一覧から消える
- 「詳細」ボタンをクリックして「ユーザー詳細」へ
- 「ユーザー詳細」内の削除ボタンをクリック
- アラートが出るのでOKをクリック
- 「ユーザー一覧」にリダイレクト。削除したユーザーが消えている。
掲示板詳細および編集
- メニューから「掲示板一覧」へ
- 「詳細」ボタンをクリックして各掲示板の詳細ページへ
- 掲示板詳細ページ内の編集ボタンから各掲示板の編集ページへ
- 必要事項を入力して情報を更新、掲示板詳細ページへリダイレクト
掲示板削除
- 「掲示板一覧」内の削除ボタンをクリック
- アラートが出るのでOKをクリック
- 削除された掲示板が一覧から消える
- 詳細ボタンをクリックして各掲示板の詳細ページへ
- 掲示板詳細ページ内の削除ボタンをクリック
- アラートが出るのでOKをクリック
- 「掲示板一覧」にリダイレクト。削除した掲示板が消えている
ユーザー検索
- 「ユーザー一覧」内の検索窓に検索語句を入力しroleを選択、検索ボタンを押す
- 引っかかったユーザーのみ表示される
掲示板検索
- 「掲示板一覧」内の検索窓に検索語句を入力し、作成日の範囲を指定、検索ボタンを押す
- 引っかかった掲示板のみ表示される
上記を元にタスクを洗い出してIssueに投下。できる範囲でOK。
ざっくりとはできた。後はやりながら細かく分解していく。
まずはメニューにユーザー一覧および掲示板一覧へのリンクを作成する。
…の前に、Rails基礎21のコード修正をコミットしておく。今回からは最後にまとめてじゃなく、適宜コミットしながら進めていくことにする。(本来そうすべきだったんだろうけど今まで気づいてなかった…)
OK。改めてリンク作成。
途中だけど先にルーティング追加してしまったほうがやりやすそうなのでそうする。
OK、リンクの作成に戻る。
あと今回はロケールの追加も最後にまとめてじゃなく都度やっていく。
OK…と言いたいが表示するページがないと確かめようがないので、とりあえずユーザー一覧と掲示板一覧のビューを作成して問題ないか確認する。
ああ〜そうだったコントローラもないとだめね。作る。
名前空間付きのコントローラ生成するときってrails g controller
のあとどうやって書くんだっけ…忘れちゃった。
rails g controller [namespaceのグループ名]/[コントローラー名]
でいいんだな。
なんかGoogle検索がAI使えるようになったよ!って言ってきたから使うわって言ったら、検索結果の一番上に知りたかった内容表示してくれた。わざわざ結果に出ていた各ページを訪問しなくても、これが知りたかったんでしょ?っていうのをまとめて表示してくれるっぽいな。すごい。
よし、コントローラもできたのでリンクがちゃんとできてるかテスト。
よし!リンクはちゃんとできた。
今度は中身のコードが配布されてるファイルに、その中身をコピペしていく。パーシャルはまだ生成してないので生成からやる。
OK。ただ、ransack関係のエラーが出てしまって色々確認できないので、一旦検索フォームは無効にしておく(検索フォームをレンダリングしているコードをコメントアウトする)。
大まかな進め方の方針
- 基本的なCRUD機能の実装
- 削除ボタンのAjax化
- 検索機能の実装
これをユーザー→掲示板の順でやっていこうと思う。
あれ、だめだ。コメントアウトしても読み込もうとしてエラーになる。
諦めてransackの対応先にやるか。
完全に忘れてるので既存のコードを確認。それでもわからなければ初登場時のカリキュラムページを見に行こう。
(できればransackの使い方もまとめてTILに投げたいなあ…)
あ〜ransackのほうはいけたっぽいけどroleの多言語化も先にやらないとだめか。仕方がないのでそっちもやり方調べて対応する。
よし、enum_helpの概要はわかったので早速インストールする。
OK。次はロケールを追加。
できたけどページネーションもやらなきゃだ〜〜
やります…結局どれも後回しには出来ないね…
おお〜できた〜〜!
レイアウト指定してなくて通常バージョンのヘッダーになっちゃってるので、admin用のを指定する。
…と思ったけどよく考えたらAdmin::BaseControllerで指定したんだから個別にする必要ないんじゃ??
と思ったところで、継承を書き直してないことに気づいた。直す。
OK!
検索機能はさっきコントローラに書いた部分以外はコピペしたコードでもう出来上がってるみたい。詳しいことは後にして(どうせ掲示板のほうを作るときに見ることになるので)、ユーザー一覧ページを完成させにかかる。
まずは多言語化対応。
モデルの属性名ってこの場合どう多言語化するんだ??ロケールを追加したら自動でなるかな。
お、いけた!
ただfull_nameだけどうなってるのかわからんな。そんなカラム名はないからdecorator使ってるのかな。ちょいと調べてみよう。
あれ!ダメ元で普通にロケール追加したらいけちゃった。どういう理屈だ??
→ロボらんてくんに聞いて判明したのでTILに投げた
今日はここまで…なんだけど、しまったこまめなコミット忘れてた。一応今日の時点でのコミットもしときたいけど、メッセージなんにしよう?
「メニューリンク作成、ルーティング追加、enum多言語化」でいいかな。やり途中のところはスルーして完了してるとこだけ。
いや、やっぱり「メニューリンク作成、ルーティング追加、enum多言語化、コントローラ&ビューファイルの生成」にしとこう。こっちのほうが正確だ。
2023.10.13
今日もやっていく。
まずユーザー一覧ページを完成させる。
検索フォームを多言語化する。
ページネーションも見た目整えたほうがいいかな?通常の掲示板一覧を参考にしてみるか。
お、できた。見た目はこれでOKそうなので、詳細・編集・削除ボタンをそれぞれ使えるようにしていく。
…と思ったけど、ボタンのリンク自体はもうできてるなこれ。むしろリンク先をきちんと表示されるように整えないといけないな。
まずユーザー詳細ページからいくか。
これもビューの方はほぼほぼ良さそう。コントローラのアクションの中身を作らないと。
よし、OK。次は編集ページ。
エラーメッセージのパーシャル、ファイル名を「_error_message.html.erb」にしてたんだけど、コピペしたコードだと「_error_messages.html.erb」になってるな。うーーん今更全部直すの大変だからコードの法を直しちゃったけど、どちらかというと複数形のほうが良かった気はするな…。次からはそうしよう。
編集ページも見た目はOKなので、updateアクションを作っていく。
よし、編集機能が無事動くかチェック。
OK。最後に削除機能。まずは詳細ページから削除した場合の動きを作る。
よし、出来たので試す。
あれ、ボタンが反応しない…また??サーバーログ見てみよう。
リクエストがGETになってるな。確認ダイアログも出なかった。ということはTurboがうまく動いてない??
あ、確認ダイアログのロケールのキーが間違ってる。messageいらんわ。
てか直すとこ間違ってた…ユーザー一覧の方いじってた。そりゃそうなるわ。
ユーザー詳細のほうを直して無事解決。
さて、一覧の方の削除ボタンをAjax化するか。
やり方全然覚えてないのでcoment周りのコード見て思い出す…。
- Ajax化したいアクションに対応した
アクション名.turbo_stream.html.erb
というビューファイルを作る - その中に加えたい変更を書く
大まかに言うとこんな感じかな。
てかやっぱり前にまとめてた!!
なのに忘れてたとかどんだけよ…。とりあぜずこれ見ながら思い出してやろう。
よし、だいたい把握はできた。
まずはturbo_streamファイルを作る。
できた。続いて中に加えたい変更内容を書いていく!今回の場合はコンテンツの削除だからturboアクションとしてはremoveだな。ターゲットのidは…あ、そうか個々のユーザーIDが含まれるようなidを付けなきゃいけないな。まずはそれか。
idはOK。いざ中身を書いていく。
OK。書いた中身に合わせてコントローラのdestroyアクションを修正(ローカル変数user
をインスタンス変数@user
に)
出来たと思う…けどこれ一覧で削除ボタン押したときと詳細で押したときをどうやって分ければいいんだ?
とりあえず一覧で押したときにちゃんと動くかチェックする。
これはちゃんとできてた。でも詳細のほうで押したときどうなるんだ???
⁉
やってみたらなぜかユーザー一覧ページに飛んでくれた…いや嬉しいけどなぜ??
あ、なんだ。単にredirect_to
を消し忘れてただけだ。消してやってみよう。
あ、だめだ。リロードしないと消えない。うーん。
ん〜〜なんでだめなんだ。というかこれひょっとしてAjax化する必要ないのかな。
もう一旦やめにして普通にリダイレクトするようにしてしまおう。
あ!ファイル名間違えてる!destroy.turbo_stream.html.erb
じゃなくてdestroy.turbo_stream.erb
だ。.html
がいらない!
出来た〜〜!
…で、詳細ページから削除した場合は結局どうする??
正直Ajax化はしなくていい気はするけどせっかくだから挑戦してみるか。ただ今日はもう時間なので続きは明日。
以前書いたTurbo StreamのまとめをマークダウンでエクスポートしてTILに上げとこう。
あと役立ちそうな記事のリンク貼っとこ。
しまった〜〜〜またコミットするの忘れてた。今日の分だけでもしよう…メッセージどうしようかな。
「ユーザー一覧・詳細・編集ページの作成。およびユーザー編集・削除機能の実装」でいくか。
2023.10.14
今日は遷移元による処理の分岐から。とりあえずやってみて、うまくいかないようならリダイレクト一本にしちゃおう。
request.referer
で遷移元のURLを取得できるらしいのでそれでやってみる。
…の前に、今のままで詳細ページから削除ボタン押すとどうなるのか気になるのでやってみる。ターゲットidがページ内にないから何も起こらないとかになるのかな?
あ〜押しても一見何も起こらないけど、レコードの削除はされてるからリロードすると「そのユーザー部ジェクト無いよ」ってエラーになるんだな。
よし、確かめられたので分岐を実装する。
ん〜〜やってみたけど、これひょっとしてredirect_toってビューでは使えない?そんなメソッド無いよって言われちゃった。
ってことはアクションのほうで分岐するしかないか。ますますこれやんなくていいんじゃね感が高まってきたけど、ここまで調べたし一応やるか。
お〜できた。参考にした記事のリンク貼っとこ。
よし!ユーザーの方はできたので次は掲示板に移る。
の前に今の状態でコミットしとく。
デザイン見る限り、基本はユーザーのページをベースにして中身変えるだけで行けそうだな。
というわけでまずはビューファイルのコードをコピペして適宜書き換える。
掲示板一覧に表示する項目、「作成日」って書いてあるけどサンプル動画見ると「作成日時」になってるな。とりあえず「作成日時」にしておこう。
よし、indexのビューとアクションを仮に作ったのでテストしてみる。
OK!検索機能は後回しにすることにして、次に詳細ページを作る。
OK、出来てるか確認。
サンプル動画見て気づいたけど本文も要るな。書いてないけど。追加する。
よし。次、編集ページ。
一旦休憩。
OKなんだけどちょっと見た目がサンプルと違うので合わせたい。たぶん通常の掲示板編集を参考にしたほうが良さそうかな。
そもそもbodyがtext_field
になってるからだ。text_area
に直す。で、rows: 10
だな。
OK。次は編集機能を完成させる。updateアクションの中身を書く。
よしOK。
次、削除機能。こっちはもう最初からAjax化して作る。
よし確認。
できた〜〜〜〜!!
これで残りは掲示板の検索機能のみ。ワード検索はそのままでいいとして、作成日の範囲指定検索のやり方を調べなくては。
う〜ん結構難しそう。とりあえず参考になりそうな記事のリンク。
日付検索の基本はわかった。date_field
と_gteq
、_lteq
を使えばいいんだな。
ただしこのままだと_lteq
が「指定の日付の0:00まで」になってしまって事実上その日付が含まれないので、カスタム述語を作ることで対応すると。
今日はここまで。明日カスタム述語を作るところから再開する。
コミットメッセージは「掲示板一覧・詳細・編集ページの作成、および掲示板編集・削除機能の実装。ransack設定ファイルの追加」にしよう。
2023.10.15
今日はransackの設定ファイルの中身を作るところから。
OK。検索フォームのコードを新たに作った述語で書き換えてテスト。
できた!ransack設定ファイルの書き方の詳細については後で確認するとして、次は検索フォームの見た目を整えよう。今は日付選択フィールドが縦に並んじゃってるから横並びにしたい。
なるほど。me-3
は「m=マージンをe=end(今は左から右なので右)に3=$ spacer(たぶん設定で1spacer=何pxか決められる)」ってことなんだな。
ということは開始日の方のme-3
をなしにしちゃえばいいのか。
よし、きれいになった。
最後は「アクティブ・非アクティブ」ってやつか。サンプル動画見た感じ、メニューリンクの表示の話かな?ユーザー関連ページにいるときはユーザー一覧の方に色がついて、掲示板のときも然り、みたいな。
↓このページを参考にしてみよう。
いや、どっちかというとこっちかも?
う〜ん、タブ切り替えのやり方ばっかり出てきちゃうな。ロボらんてくんに聞いてみるか。
現在のページのパスが特定のパターンである場合だけclassにactiveを追加すればいいのか。
そういうメソッドがあるか調べよう。あるいは自作してもいいな。
あ、「コントローラが特定のもの」とかもできるのか。これでいけるかも。
だめだった。アクションのみ指定はできてもコントローラのみ指定はできないらしい。
ヒント見よう。
params[:controller]
でコントローラ名取得できるの!?マジか〜
いちおうできた。けど正直もっときれいな書き方絶対あるだろうなって思う…。<%= %>
の中で分岐したい場合ってどうすればいいんだ……
とりあえず確認ポイントチェックして、良さそうならローカルテストする。望ましい書き方についてはクリア後にチェックして修正することにする。
ユーザー一覧画面、作成日時も要るよね?確認ポイントには書いてないけどたぶん漏れだなこれ。
あとユーザー詳細画面も書いてないけどたんアバター要る。
掲示板一覧、タイトル部分をクリックすると詳細に飛ぶようにってあるけど、サンプル動画だとそうなってなくないか??どっちなんだろう。一旦無視しておくか。
掲示板詳細および編集ページのタイトルが個別の掲示板タイトルになっていないので修正。
確認ポイント全てクリアしたのでローカルテスト。
久々にローカルテスト一発OK!コミットしてプルリクだ。
コミットメッセージは「掲示板検索機能の実装、メニューリンクのアクティブ・非アクティブ切り替え昨日の実装=>Rails基礎22実装完了」で。
Lintチェックでrequest.referrer
じゃなくてrequest.referer
って書こうねって言われた。そっちのほうが望ましいのね。
LGTM!
休憩してから復習に入る。
復習ポイント、色々書いてあるけど修正が必要なポイントとしては、
- メニューリンクのアクティブ・非アクティブ切り替え機能
-
data: { disable_with: '送信中'}
について
って感じかな。
まずはメニューリンクの方からいくか。
submitのdata-disable-with
はRails5からデフォルトで設定されるようになっていたらしい。お前いらなかったんかい!いろんなフォームで書いちゃってるので消して回る…
OK。次は解答例のコードを見て他に直すところがないか探す。削除ボタンのAjax化はたぶんいらなかったんじゃないかなあ…
ユーザーおよび掲示板一覧は作成日時が新しい順に並び替える。
あ、やっぱりAjax化はしてないね…まあ勉強になったから良しとしよう。直す。
掲示板の日付検索部分の表示を修正。
掲示板編集のサムネイル周りのコードを修正(小さいサイズでプレビューされるように)。
ヘッダーのロゴを押すとダッシュボードに飛ぶようにする。
activerecordのロケール、共通の属性はそれだけでattributesとしてまとめられるのか??ちょっと調べてもわからないのでパス。
よし、修正はこれで終わり。
後は復習ポイントに書いてある内容をどこまで理解することにするか…
- ransackとenumを使ったプルダウン選択について
- procについて
- 可変長引数について
-
any?
メソッドについて
とりあえず可変長引数とany?
メソッドについて軽く触れておくか。
可変長引数:個数を指定しない引数のこと。
any?
メソッド:配列などのコレクションの要素に1つでも真があればtrueを返し、全ての要素が偽ならfalseを返すメソッド。ブロックを伴う場合は、各要素に対してブロックを評価し、すべての結果が偽である場合に false を返す。ブロックが真を返した時点で、ただちに true を返す。
次、procについて。
ブロックをオブジェクト化したもの、とのこと。それ以上は今の自分には難しそうなので深入りしないことにする。
次、ransackのプルダウンとそれをenumで使う方法について。
配布されたコードに最初から書いてあったから正直なにがどうなってるのか理解してない。できるところまで紐解いてみる。
enum_helpをインストールすると、属性名_i18n
というメソッドが使えるようになる。これで属性の値を翻訳済の状態で取得できる。
さらに属性名を複数形にすれば、翻訳後の属性を列挙したコレクションを取得できる。
user = User.first
user.role
# => 'general'
user.role_i18n
# => '一般'
user.roles_i18n
# => {"general" => "一般", "admin" => "管理者" }
プルダウン検索の実装、理解はできた。できたけど自力でまとめなおす元気がないのでリンク貼っとく…↑のenum_helpのと合わせればこれでわかる…
よし、TILにできる範囲でまとめた。
これにてRail基礎22、というかRails基礎完了!!