Closed46

Rails応用1

なななななな

「デバッグツールを使うときはrailsサーバーを立ち上げているコンテナの名前を確認する」「該当のコンテナIDをattachする」ってあるけど、これは今やっといたほうがいいのか?

なななななな

???
やってみたけど、なんか入力受付みたいになった…。docker attach コンテナIDでデバッグツールが起動したってことかな?どう使うものなのかよくわからないけど、このあと課題の中で出てくるんだろうか。とりあえず終了して次に進もう。

なななななな

さっそく最初の課題に取り組む。まずは環境を確認。

開発環境

  • Ruby 3.1.4
  • Node 15.14.0
  • yarn 1.22.19
  • データベース:SQLite3
なななななな

まず実際にエラーを起こしてみよう。
記事を作成して、その記事の編集ページへ。そこで画像ブロックを挿入するも実際には画像をアップロードしないままプレビュー画面を開く。
これでエラーが出るはず。

なななななな

記事を作成後、なにもせずにプレビューしたら問題なく表示された。次は↑を試す。

なななななな

出た。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.
なななななな

導入完了。
エラーが出てるのは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になってるってことかな。

なななななな

ということはおそらく:lgがアップロードされた画像を指してるんだろうな。
これは普通にRubyのキーなのか、Slimの記法なのか??

なななななな

記事編集フォームを見てみよう。それでわかるかも。

だめだぜんぜんわからん。

なななななな

Articleモデルのbuild_bodyメソッドを直せばいい気がする。
elsif article_block.medium?の部分を、elsif article_block.medium? && 画像がアップロードされているにすれば、画像がアップロードされてなければ無視されるんじゃないかな。

なななななな

問題は画像がアップロードされているかどうかをどう確認するかだな…。画像アップロードの仕組みがどうなってるのか確認しないと。

なななななな

う〜んblockableの正体がいまいちわからないけど、どうもarticle_blockとその実際の中身を結びつけてるっぽい?モデルとしては存在しないのに、なぜかarticle_blockblockablebelongs_toしてるんだよなあ。

とりあえずさっきの「画像がアップロードされている」をarticle_block.blockable.name.present?にしてみた。
そうしたら「TypeError - no implicit conversion of nil into String」が出たので、article_blocksentenceでも”アップロード済みのmedium”でもembedでもない場合、空の文字列をresultに代入するようにしたらいけた。

なななななな

全然いいやり方じゃないと思うしそもそも自分でもよく意味わかってないけど、一旦テスト通るかだけ確認しちゃおう。

なななななな

テストは通った。

けど今ヒント確認したら、ひょっとしてビューの方いじればいいのかもって思った…。local_assignsメソッドについて調べてみよう。

なななななな

ビューいじったら行けたわ…驚くほど簡単だった。
local_assignsで取得したハッシュを変数mediumに代入してるから、medium[:name]がnilでも空欄でもないときだけ画像表示するようにした。

なななななな

ヒント見てよかった〜というか最初にちゃんとlocal_assginsについて調べるべきだった。反省。

なななななな

よし、テスト通った。
自分でも書くの推奨とのことなので、挑戦してみるか。

なななななな

RSpec完全に忘れてる〜。前に自分が書いたやつと今回の分のお手本めちゃくちゃ見ながらやっちゃった。
とりあえず書けたし走らせてみよう。

なななななな

ん?実行されてない気がする。どこかで指定しなきゃいけないんだっけ。

なななななな

ファイル指定すればとりあえずできるか。やってみよう。

なななななな

OK、無事できた。しかしホントlinkとbuttonの区別つきづらいな…まあコード見ればわかるんだけど、正直いちいち確認するのめんどいし、全部click_onで統一したくなる。

よし、今度こそプルリクする。

なななななな

復習パート

RSpec、FactoryBotの作成とかからやるべきだったらしい。次回からはそうしよう。
というかそのために一回RSpecの基本的な使い方まとめておいたほうがいいかも。いちいちカリキュラム見直すのめんどい。

なななななな

あと、ビューの条件分岐はmedium.image_urlが存在するかどうかで良かったらしい。これはせっかくbetter_errors入れたんだからエラー画面のコンソールで確認してみればよかったな。

なななななな
  • エラーが出たときは、とりあえずサーバーのログも確認する
  • 「何かがnilになっている」というエラーなら、コンソールを使ってどの部分がnilなのか確認する
なななななな

RSpecの基本的な使い方はやっぱり一旦まとめておこう。TILに突っ込んでおけば見返しやすい。

なななななな

コード修正が終わってRSpecのまとめ中。今日はここまでにして明日はまとめの続きから。

なななななな

RSpecまとめ終了!これを記事にするのもいいかもなどと思った。

なななななな

あとエラーが出たときにどう対応してどう解決したかをまとめる場所を作っとくのもいいかなと思った。これまでの分が分散しちゃってるからそれが厄介だけど。

追記
とりあえず今回の分だけだけどTILに投げた。

なななななな

課題から話がそれるけど、この「学習ログ&アウトプットどうしよう問題」をいっそのことアプリにするとかもアイデアとしては有りだよね。学習ログをつけるだけでそれをアウトプットにつなげてくれるなにかがあったらすごく便利。
いちおうメモとしてどこかに書いとくか。

このスクラップは6ヶ月前にクローズされました