Rails応用1
2023.11.11
まずは環境構築。
「デバッグツールを使うときはrailsサーバーを立ち上げているコンテナの名前を確認する」「該当のコンテナIDをattachする」ってあるけど、これは今やっといたほうがいいのか?
???
やってみたけど、なんか入力受付みたいになった…。docker attach コンテナID
でデバッグツールが起動したってことかな?どう使うものなのかよくわからないけど、このあと課題の中で出てくるんだろうか。とりあえず終了して次に進もう。
さっそく最初の課題に取り組む。まずは環境を確認。
開発環境
- Ruby 3.1.4
- Node 15.14.0
- yarn 1.22.19
- データベース:SQLite3
yarnのバージョンはどう確認するんだろう。調べる
yarn --version
でいいらしい。
確認した。環境欄に追記OK。yarnのバージョンは問題なしだな。
まず実際にエラーを起こしてみよう。
記事を作成して、その記事の編集ページへ。そこで画像ブロックを挿入するも実際には画像をアップロードしないままプレビュー画面を開く。
これでエラーが出るはず。
記事を作成後、なにもせずにプレビューしたら問題なく表示された。次は↑を試す。
出た。URIを生成しようにもロケーションがNilだよって言われてるな。
ArgumentError in Admin::Articles::Previews#show
Showing /v3_advanced_rails/app/views/shared/_media_image.html.slim where line #5 raised:
Nil location provided. Can't build URI.
本格的な問題特定に入る前に、better errors
入れとくか。
導入完了。
エラーが出てるのはviews/shared/_media_image.html.slim
か。.slim
っていう拡張子は初めて見るな。課題の学習内容にSlim
ってあったからそれ関係だな。Gemかな?
まずSlimについて調べてみよう。
公式ドキュメントこれかな。
簡潔にまとまってる記事ならこれとか。
なるほど、HTMLをもっとRubyみたいに簡潔(slim)に書けるようにするGemなんだな。これは便利。
さっきのslimファイルを通常のERBに直すとどうなるのか解読してみよう。
ruby:
medium = local_assigns[:medium]
.media-image
= image_tag medium.image_url(:lg)
上はまず置いといて、下はこうかな。
<div class="media-image">
<%= image_tag medium.image_url(:lg) %>
</div>
ruby:
はrubyコードの埋め込みらしい。
つまり↑のSlimファイルはERBに直すと
<% medium = local_assigns[:medium] %>
<div class="media-image">
<%= image_tag medium.image_url(:lg) %>
</div>
ってことかな
ということは、medium
もしくは:lg
に問題がある、というかnilになってるってことかな。
image_url
の機能とエラー内容的に、:lg
がnilなのかな。
そうっぽい。
ということはおそらく:lg
がアップロードされた画像を指してるんだろうな。
これは普通にRubyのキーなのか、Slimの記法なのか??
記事編集フォームを見てみよう。それでわかるかも。
↓
だめだぜんぜんわからん。
mediaってmediumの複数形だったんか…知らなかった。
Articleモデルのbuild_body
メソッドを直せばいい気がする。
elsif article_block.medium?
の部分を、elsif article_block.medium? && 画像がアップロードされている
にすれば、画像がアップロードされてなければ無視されるんじゃないかな。
問題は画像がアップロードされているかどうかをどう確認するかだな…。画像アップロードの仕組みがどうなってるのか確認しないと。
う〜んblockable
の正体がいまいちわからないけど、どうもarticle_block
とその実際の中身を結びつけてるっぽい?モデルとしては存在しないのに、なぜかarticle_block
はblockable
にbelongs_to
してるんだよなあ。
とりあえずさっきの「画像がアップロードされている」をarticle_block.blockable.name.present?
にしてみた。
そうしたら「TypeError - no implicit conversion of nil into String」が出たので、article_block
がsentence
でも”アップロード済みのmedium
”でもembed
でもない場合、空の文字列をresult
に代入するようにしたらいけた。
全然いいやり方じゃないと思うしそもそも自分でもよく意味わかってないけど、一旦テスト通るかだけ確認しちゃおう。
テストは通った。
けど今ヒント確認したら、ひょっとしてビューの方いじればいいのかもって思った…。local_assigns
メソッドについて調べてみよう。
なるほど〜。
- パーシャルで使うヘルパーメソッド
-
render
での呼び出し時に各ローカル変数にどんな値が代入されたかをハッシュ形式で取得できる
ビューいじったら行けたわ…驚くほど簡単だった。
local_assigns
で取得したハッシュを変数medium
に代入してるから、medium[:name]
がnilでも空欄でもないときだけ画像表示するようにした。
ヒント見てよかった〜というか最初にちゃんとlocal_assgins
について調べるべきだった。反省。
よし、テスト通った。
自分でも書くの推奨とのことなので、挑戦してみるか。
RSpec完全に忘れてる〜。前に自分が書いたやつと今回の分のお手本めちゃくちゃ見ながらやっちゃった。
とりあえず書けたし走らせてみよう。
ん?実行されてない気がする。どこかで指定しなきゃいけないんだっけ。
ファイル指定すればとりあえずできるか。やってみよう。
OK、無事できた。しかしホントlinkとbuttonの区別つきづらいな…まあコード見ればわかるんだけど、正直いちいち確認するのめんどいし、全部click_on
で統一したくなる。
よし、今度こそプルリクする。
LGTM!やった〜!
復習パート
RSpec、FactoryBotの作成とかからやるべきだったらしい。次回からはそうしよう。
というかそのために一回RSpecの基本的な使い方まとめておいたほうがいいかも。いちいちカリキュラム見直すのめんどい。
あと、ビューの条件分岐はmedium.image_url
が存在するかどうかで良かったらしい。これはせっかくbetter_errors入れたんだからエラー画面のコンソールで確認してみればよかったな。
- エラーが出たときは、とりあえずサーバーのログも確認する
- 「何かが
nil
になっている」というエラーなら、コンソールを使ってどの部分がnil
なのか確認する
RSpecの基本的な使い方はやっぱり一旦まとめておこう。TILに突っ込んでおけば見返しやすい。
まずはコードを修正しよう。
コード修正が終わってRSpecのまとめ中。今日はここまでにして明日はまとめの続きから。
2023.11.12
RSpecの基本まとめ続きから。
RSpecまとめ終了!これを記事にするのもいいかもなどと思った。
あとエラーが出たときにどう対応してどう解決したかをまとめる場所を作っとくのもいいかなと思った。これまでの分が分散しちゃってるからそれが厄介だけど。
追記
とりあえず今回の分だけだけどTILに投げた。
課題から話がそれるけど、この「学習ログ&アウトプットどうしよう問題」をいっそのことアプリにするとかもアイデアとしては有りだよね。学習ログをつけるだけでそれをアウトプットにつなげてくれるなにかがあったらすごく便利。
いちおうメモとしてどこかに書いとくか。