tag:crieit.net,2005:https://crieit.net/tags/rails%E3%81%A7%E3%82%A2%E3%83%97%E3%83%AA%E3%82%92%E4%BD%9C%E3%82%8B/feed 「railsでアプリを作る」の記事 - Crieit Crieitでタグ「railsでアプリを作る」に投稿された最近の記事 2020-12-31T18:28:25+09:00 https://crieit.net/tags/rails%E3%81%A7%E3%82%A2%E3%83%97%E3%83%AA%E3%82%92%E4%BD%9C%E3%82%8B/feed tag:crieit.net,2005:PublicArticle/16453 2020-12-31T18:28:25+09:00 2020-12-31T18:28:25+09:00 https://crieit.net/posts/2020-12-31 2020.12.31 * テスト機能作成 <h2 id="本日のゴール"><a href="#%E6%9C%AC%E6%97%A5%E3%81%AE%E3%82%B4%E3%83%BC%E3%83%AB">本日のゴール</a></h2> <p>■ テスト機能を作る<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fd6fe1f64804.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fd6fe1f64804.png?mw=700" alt="image.png" /></a><br /> 設計を少し見直しました。<br /> 単語の編集機能は無くして、追加・削除のみにします。</p> <h2 id="Test画面生成"><a href="#Test%E7%94%BB%E9%9D%A2%E7%94%9F%E6%88%90">Test画面生成</a></h2> <p>チャプターごとに単語テストができる画面を作ります!<br /> 久々にこのコマンド<br /> <code>$ rails g controller Tests</code><br /> <strong>tests_controller.rb</strong>にテスト画面表示用のindexアクションを作成します。</p> <pre><code>class TestsController < ApplicationController def index @chapter_id = params[:chapter_id] @words = Word.where(chapter_id: @chapter_id) end </code></pre> <p><strong>routes.rb</strong>には以下を追加</p> <pre><code>get 'test/', to: 'tests#index' </code></pre> <p><strong>chapters/index.html.erb</strong>にテスト画面へのリンクを追加</p> <pre><code><% @chapters.each do |chapter| %> <div> <%= chapter.name %> <%= link_to 'Show Words', words_path(chapter_id: chapter.id) %> <%= link_to 'TEST', test_path(chapter_id: chapter.id) %> </div> <% end %> </code></pre> <p>こんな感じです<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fed92d065164.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fed92d065164.png?mw=700" alt="image.png" /></a></p> <p>テスト画面のviewを作成します。<br /> <strong>tests/index.html.erb</strong></p> <pre><code><h1>TEST - CHAPTER<%= @chapter_id %></h1> <div> <%= form_with url: score_path do |f| %> <% @words.each do |word| %> <div> <%= word.english %> <%= f.text_field :"answers[#{word.id}]" %> </div> <% end %> <%= f.hidden_field :chapter_id, :value => @chapter_id %> <%= f.submit 'SUBMIT' %> <% end %> </div> </code></pre> <p>単語のIDと回答をanswersというハッシュに格納してコントローラに渡すようにしています。<br /> (キーがID, 回答が値)<br /> hidden_fieldのチャプターIDはスコア画面で表示させるためのものです。</p> <p>画面はこうなりました。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fed9470d2bca.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fed9470d2bca.png?mw=700" alt="image.png" /></a></p> <h2 id="テストを採点する"><a href="#%E3%83%86%E3%82%B9%E3%83%88%E3%82%92%E6%8E%A1%E7%82%B9%E3%81%99%E3%82%8B">テストを採点する</a></h2> <p><strong>tests_controller.rb</strong></p> <pre><code> def score answers = params[:answers] should_retest_values = {} session[:answers] = answers # 正誤判定 answers.each do |answer| should_retest = is_wrong(answer) should_retest_values[answer[0]] = should_retest end # wordsテーブルのshould_retestを更新 should_retest_values.each do |k, v| word = Word.find(k) word.should_retest = v word.save end # 正答数を算出 score = count_correct_answers # テンプレートに返却 redirect_to showscore_path(score: score, chapter_id: params[:chapter_id]) end def show @score = params[:score] @chapter_id = params[:chapter_id] @words = Word.where(chapter_id: @chapter_id) @answers = session[:answers] end private def is_wrong(answer) correct_answer = Word.find(answer[0]) return answer[1] != correct_answer.japanese end def count_correct_answers Word.where(should_retest: false).size end </code></pre> <p>scoreメソッドがやっている処理は以下のとおりです。<br /> 1. viewから渡された回答をセッションに入れる(スコア画面で表示させるため)<br /> 2. 正誤判定し、{ ID: 再テストtrue/false } という形式のハッシュを作成<br /> 3. ハッシュの値をもとにDB(wordsテーブルのshould_retestカラム)を更新<br /> 4. スコア(正答数)を算出<br /> 5. スコア画面にリダイレクト</p> <p>showメソッドはスコア画面を表示します。<br /> ルーティングは以下のようにしました。<br /> <strong>routes.rb</strong></p> <pre><code> post 'score/', to:'tests#score' get 'showscore/', to:'tests#show' </code></pre> <h2 id="スコア画面作成"><a href="#%E3%82%B9%E3%82%B3%E3%82%A2%E7%94%BB%E9%9D%A2%E4%BD%9C%E6%88%90">スコア画面作成</a></h2> <p><strong>tests/show.html.erb</strong></p> <pre><code><h1>SCORE - CHAPTER<%= @chapter_id %></h1> <div> score:<%= @score %> </div> <div> <% @words.each do |word| %> <p> <%= word.english %> <%= word.japanese %> <%= @answers[word.id.to_s] %> </p> <% end %> </div> </code></pre> <p>showメソッドから渡された変数を使ってスコア、英単語・正解・ユーザの回答を表示させています。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fed989564e2a.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fed989564e2a.png?mw=700" alt="image.png" /></a></p> <p>DBの値もちゃんと更新されました!<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fed99768263a.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fed99768263a.png?mw=700" alt="image.png" /></a></p> <p>おわり*0 v 0</p> same.__.same tag:crieit.net,2005:PublicArticle/16341 2020-12-11T23:17:05+09:00 2020-12-11T23:17:05+09:00 https://crieit.net/posts/2020-12-11-chapter 2020.12.11 * chapter機能 <h2 id="本日のゴール"><a href="#%E6%9C%AC%E6%97%A5%E3%81%AE%E3%82%B4%E3%83%BC%E3%83%AB">本日のゴール</a></h2> <p>■ chapterごとに登録・削除できるようにする<br /> <a href="https://crieit.now.sh/upload_images/16e8b3cd8b7371ebe0bc6e70171476af5fb483db2ca67.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/16e8b3cd8b7371ebe0bc6e70171476af5fb483db2ca67.png?mw=700" alt="image" /></a></p> <h2 id="chapterテーブルの初期値を投入"><a href="#chapter%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%81%AE%E5%88%9D%E6%9C%9F%E5%80%A4%E3%82%92%E6%8A%95%E5%85%A5">chapterテーブルの初期値を投入</a></h2> <p>Index and Edit and Delete画面を作りたいと思います。<br /> 今までwordsテーブルのchapter_idはnullのままにしていたので、まずここを登録できるようにします。</p> <p>chapterテーブルはとりあえず初期データを登録しておくことにするので、seed.rbを使います。<br /> <strong>db/seed.rb</strong></p> <pre><code># This file should contain all the record creation needed to seed the database with its default values. # The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup). # # Examples: # # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) # Character.create(name: 'Luke', movie: movies.first) for i in 1..5 do Chapter.create(name: "chapter#{i}") end </code></pre> <p>chapter1~chapter5を登録するスクリプトです。<br /> コマンドでデータを投入します。<br /> <code>$ rails db:seed</code><br /> sqliteでテーブルを確認すると<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fb4aa8ee03b6.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fb4aa8ee03b6.png?mw=700" alt="image.png" /></a><br /> ちゃんと投入できていました!</p> <h2 id="chapter一覧画面作成"><a href="#chapter%E4%B8%80%E8%A6%A7%E7%94%BB%E9%9D%A2%E4%BD%9C%E6%88%90">chapter一覧画面作成</a></h2> <p>まずChapterコントローラを作成して、indexで一覧表示させます。<br /> <code>$ rails g controller Chapters</code><br /> <strong>chapters_controller.rb</strong></p> <pre><code>class ChaptersController < ApplicationController def index @chapters = Chapter.all end end </code></pre> <p><strong>views/chapters/index.html.erb</strong></p> <pre><code><% @chapters.each do |chapter| %> <div> <%= chapter.name %> </div> <% end %> </code></pre> <h2 id="単語をchapterごとに表示させる"><a href="#%E5%8D%98%E8%AA%9E%E3%82%92chapter%E3%81%94%E3%81%A8%E3%81%AB%E8%A1%A8%E7%A4%BA%E3%81%95%E3%81%9B%E3%82%8B">単語をchapterごとに表示させる</a></h2> <p>先ほど作成した<strong>views/chapters/index.html.erb</strong>にwords一覧画面へのリンクを付けます。<br /> リンクが呼ぶのはwordsコントローラのindexアクションです。パラメータとしてchapter_idを渡します。</p> <pre><code><% @chapters.each do |chapter| %> <div> <%= chapter.name %> <%= link_to 'Show Words', words_path(chapter_id: chapter.id) %> </div> <% end %> </code></pre> <p><a href="">localhost:3000/chapters</a>はこうなりました<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fceeae8274b7.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fceeae8274b7.png?mw=700" alt="image.png" /></a></p> <p>indexアクションは今までwordsを全件抽出していましたが、これをchapter_idで絞り込むようにします。<br /> <strong>words_controller.rb</strong></p> <pre><code>class WordsController < ApplicationController def index @words = Word.where(chapter_id: params[:chapter_id]) end </code></pre> <p>DBにレコードを登録しておいて(chapter_id=1が3件、chapter_id=2が2件にしました)<br /> <a href="">localhost:3000/chapters</a>からリンクを踏んでみます。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fceebde46244.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fceebde46244.png?mw=700" alt="image.png" /></a><br /> URLは<a href="">http://localhost:3000/words?chapter_id=1</a>となっていました。<br /> ここをTOP画面にしたいので、<strong>routes.rb</strong>を修正します。</p> <pre><code>Rails.application.routes.draw do root 'chapters#index' </code></pre> <h2 id="index, create, deleteをまとめる"><a href="#index%2C+create%2C+delete%E3%82%92%E3%81%BE%E3%81%A8%E3%82%81%E3%82%8B">index, create, deleteをまとめる</a></h2> <p>chapterを選択した後の画面でwordsの一覧表示、追加、削除を行えるようにします。<br /> <strong>words/index.html.erb</strong></p> <pre><code><h1>WORDS - CHAPTER<%= @chapter_id %></h1> <div> <% @words.each do |word| %> <div> ID: <%= word.id %> | ENGLISH: <%= word.english %> | JAPANESE: <%= word.japanese %> <%= button_to 'Delete', word_path(word), method: :delete %> ---------- </div> <% end %> <p>*ADD NEW WORDS*</p> <%= render 'form' %> </div> </code></pre> <p>以前作成していたフォームを追加して、editを削除しました。<br /> <strong>_form.html.erb</strong></p> <pre><code><%= form_with model: @new, local:true do |f| %> <div> <%= f.label :english %> <%= f.text_field :english %> </div> <div> <%= f.label :japanese %> <%= f.text_field :japanese %> </div> <%= f.hidden_field :chapter_id, :value => @chapter_id %> <%= f.submit %> <% end %> </code></pre> <p>model: @word だった部分を@newとし(words/index.html.erbにはもともと@wordsを渡しているのでややこしいから変更)、hidden_fieldを使ってchapter_idが勝手に登録されるようにしています。<br /> <strong>words_controller</strong>も修正</p> <pre><code>class WordsController < ApplicationController def index @chapter_id = params[:chapter_id] @words = Word.where(chapter_id: params[:chapter_id]) @new = Word.new end 〜中略〜 def create @word = Word.new(word_params) @word.save redirect_to words_path(word_params) end </code></pre> <p>indexアクションにはフォームで使用する@newを追加、<br /> createアクションにはredirect_toの引数を追加しました。word_paramsは[:chapter_id]を引数として受け取るように定義してあるので、これによってチャプターの単語一覧画面にリダイレクトされます。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fd37ece72e9c.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fd37ece72e9c.png?mw=700" alt="image.png" /></a><br /> こんな感じになりました</p> <h2 id="宿題"><a href="#%E5%AE%BF%E9%A1%8C">宿題</a></h2> <p>ルーティングやアクションをいろいろ変更したので、リダイレクト先がおかしかったり使わないviewsが出てきたりしてしまいました。<br /> 整理したい!!</p> <p>おわり*0 v 0</p> same.__.same tag:crieit.net,2005:PublicArticle/16225 2020-11-17T17:27:34+09:00 2020-11-17T17:27:34+09:00 https://crieit.net/posts/2020-11-17-5fb389769c73b 2020.11.17 * 画面設計 <h2 id="本日のゴール"><a href="#%E6%9C%AC%E6%97%A5%E3%81%AE%E3%82%B4%E3%83%BC%E3%83%AB">本日のゴール</a></h2> <p>■ 画面設計を考える<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fb388da74327.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fb388da74327.png?mw=700" alt="image.png" /></a><br /> こんな感じにしていきたいと思います。</p> <p>おわり*0 v 0</p> same.__.same tag:crieit.net,2005:PublicArticle/16222 2020-11-16T18:01:31+09:00 2020-11-16T18:01:31+09:00 https://crieit.net/posts/2020-11-16-5fb23feb9b91e 2020.11.16 * 編集機能 <h2 id="本日のゴール"><a href="#%E6%9C%AC%E6%97%A5%E3%81%AE%E3%82%B4%E3%83%BC%E3%83%AB">本日のゴール</a></h2> <p>■ 編集機能作成</p> <h2 id="editアクション作成"><a href="#edit%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E4%BD%9C%E6%88%90">editアクション作成</a></h2> <p>まず編集画面に遷移させるアクションを作成します。<br /> <strong>words_controller.py</strong></p> <pre><code> def edit @word = Word.find(params[:id]) end </code></pre> <p>showアクションと同じく、idをキーに単語を1つ探してviewに渡すという処理です。</p> <h2 id="createアクション作成"><a href="#create%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E4%BD%9C%E6%88%90">createアクション作成</a></h2> <p>続いて、viewから受け取った値をDBに格納するアクションを作成します。<br /> <strong>words_controller.py</strong></p> <pre><code> def update @word = Word.find(params[:id]) @word.update(word_params) redirect_to words_path end 中略 private def word_params params.require(:word).permit(:english, :japanese) end </code></pre> <p>処理の内容は以下の通り。<br /> 1. idをキーに更新対象の単語を探す<br /> 2. viewから受け取った引数をword_paramsに渡し、updateメソッドでDB更新<br /> 3. 一覧画面にリダイレクト</p> <h2 id="view作成"><a href="#view%E4%BD%9C%E6%88%90">view作成</a></h2> <p>最後に編集画面を作成します。<br /> <strong>words/edit.html.erb</strong></p> <pre><code><%= render 'form' %> </code></pre> <p><a href="https://crieit.net/posts/2020-11-10">第3回</a>の時にフォームのパーシャルを作成しているので、editでもこれを使います。</p> <p><a href="">http://localhost:3000/words/1/edit</a>にアクセスしてみます。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fb226913063c.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fb226913063c.png?mw=700" alt="image.png" /></a><br /> 登録済みの値が表示されました!</p> <p>値を変えてSaveボタンを押してみます。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fb226c0ad05b.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fb226c0ad05b.png?mw=700" alt="image.png" /></a><br />  ↓ボタンクリック<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fb226ea153ae.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fb226ea153ae.png?mw=700" alt="image.png" /></a><br /> 更新できました!<br /> と思ったらIDが5になっている 0 _ 0</p> <h2 id="フォームのパーシャルを修正"><a href="#%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E3%81%AE%E3%83%91%E3%83%BC%E3%82%B7%E3%83%A3%E3%83%AB%E3%82%92%E4%BF%AE%E6%AD%A3">フォームのパーシャルを修正</a></h2> <p>updateを実行するはずがcreateしてしまっている原因はフォームにありそうです。<br /> <strong>words/_form.html.erb</strong></p> <pre><code><%= form_with scope: :word, url: words_path, local:true do |f| %> <div> <%= f.label :english %> <%= f.text_field :english %> </div> <div> <%= f.label :japanese %> <%= f.text_field :japanese %> </div> <%= f.submit %> <% end %> </code></pre> <p>1行目の<strong>url: words_path</strong>が<strong>words#create</strong>を指しているので削除してみます。</p> <pre><code><%= form_with scope: :word, local:true do |f| %>  以下略 </code></pre> <p><a href="">http://localhost:3000/words/new</a>にアクセスして<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fb23d7a4c1b3.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fb23d7a4c1b3.png?mw=700" alt="image.png" /></a><br /> Saveボタンクリック↓<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fb23d438e5bc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fb23d438e5bc.png?mw=700" alt="image.png" /></a><br /> 0 _ 0...</p> <p>いろいろ調べて以下に落ち着きました。<br /> <strong>words/_form.html.erb</strong></p> <pre><code><%= form_with model: @word, local:true do |f| %> </code></pre> <p><strong>words_controller.rb</strong></p> <pre><code> def new @word = Word.new end </code></pre> <p>仕組みがあんまり理解できていないのでもやもやする....</p> <h2 id="editのリンク作成"><a href="#edit%E3%81%AE%E3%83%AA%E3%83%B3%E3%82%AF%E4%BD%9C%E6%88%90">editのリンク作成</a></h2> <p>一覧画面から編集画面に遷移できるようリンクを作っておきます。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fb227f577704.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fb227f577704.png?mw=700" alt="image.png" /></a><br /> editはedit_word_pathというルーティングになっているので、index.html.erbに<br /> <code><%= button_to 'Delete', word_path(word), method: :delete %></code><br /> という行を追加します。</p> <p><strong>words/index.html.erb</strong></p> <pre><code><h1>INDEX</h1> <div> <% @words.each do |word| %> <div> ID: <%= word.id %> | ENGLISH: <%= word.english %> | JAPANESE: <%= word.japanese %> <%= button_to 'Edit', edit_word_path(word), method: :get%> <%= button_to 'Delete', word_path(word), method: :delete %> ---------- </div> <% end %> </div> </code></pre> <p><a href="">http://localhost:3000/words</a>にアクセス</p> <p>これで一通りのCRUDが完成しました〜🎉</p> <p>おわり*0 v 0</p> same.__.same tag:crieit.net,2005:PublicArticle/16214 2020-11-12T23:37:19+09:00 2020-11-12T23:37:19+09:00 https://crieit.net/posts/2020-11-12 2020.11.12 * 単語の一覧表示 <h2 id="本日のゴール"><a href="#%E6%9C%AC%E6%97%A5%E3%81%AE%E3%82%B4%E3%83%BC%E3%83%AB">本日のゴール</a></h2> <p>■ 一覧表示作成<br /> ■ トップ画面にリンクを作成</p> <h2 id="indexアクション作成"><a href="#index%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E4%BD%9C%E6%88%90">indexアクション作成</a></h2> <p>前回showアクションを一覧表示用のアクションにしましたが、単語のIDを指定して全件表示するのはおかしいです。<br /> Railsの定石通り、全件表示はindexアクションにします。<br /> <strong>words/index.html.erb</strong>を新しく作成します。</p> <pre><code><h1>INDEX</h1> <div> <% @words.each do |word| %> <div> ID: <%= word.id %> | ENGLISH: <%= word.english %> | JAPANESE: <%= word.japanese %> <%= button_to 'Delete', word_path(word), method: :delete %> </div> <% end %> </div> </code></pre> <p>中身はh1タグ以外すべてshow.html.erbのコピペです。</p> <p>続いてコントローラ!<br /> <strong>words_controller.rb</strong></p> <pre><code>class WordsController < ApplicationController def index @words = Word.all end 以下略 </code></pre> <p>先頭にindexアクションを作りました。</p> <p><a href="">http://localhost:3000/words</a>にアクセスしてみます。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fad442f032e1.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fad442f032e1.png?mw=700" alt="image.png" /></a><br /> やったー!</p> <h2 id="showアクションを本来の姿に戻す"><a href="#show%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E6%9C%AC%E6%9D%A5%E3%81%AE%E5%A7%BF%E3%81%AB%E6%88%BB%E3%81%99">showアクションを本来の姿に戻す</a></h2> <p>IDを指定して1件だけ表示するやつに戻します。<br /> <strong>words_controller.rb</strong> ※showメソッドのみ抜粋</p> <pre><code> def show @word = Word.find(params[:id]) end </code></pre> <p><strong>words/show.html.erb</strong></p> <pre><code><h1>SHOW</h1> <div> ID: <%= @word.id %> | ENGLISH: <%= @word.english %> | JAPANESE: <%= @word.japanese %> </div> </code></pre> <p><a href="">http://localhost:3000/words/1</a>にアクセスします。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fad45a8dbe18.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fad45a8dbe18.png?mw=700" alt="image.png" /></a><br /> 無事に本来の姿に戻りました。</p> <h2 id="トップ画面にindex, newのリンクを作る"><a href="#%E3%83%88%E3%83%83%E3%83%97%E7%94%BB%E9%9D%A2%E3%81%ABindex%2C+new%E3%81%AE%E3%83%AA%E3%83%B3%E3%82%AF%E3%82%92%E4%BD%9C%E3%82%8B">トップ画面にindex, newのリンクを作る</a></h2> <p><a href="">http://localhost:3000/words/</a>や<a href="">http://localhost:3000/words/new</a>にいちいちアクセスするのが面倒なので、ついでにリンクを作ってしまいます。<br /> <a href="https://crieit.net/posts/2-5fa913cb5e444">第2回目の投稿</a>で作成したトップ画面を使うことにしました。<br /> <strong>top/index.html.erb</strong></p> <pre><code><h1>*WELCOME*</h1> <p><%= link_to 'Add A Word', new_word_path %></p> <p><%= link_to 'Show All Words', words_path %></p> </code></pre> <p><a href="">http://localhost:3000/</a>にアクセス<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fad48828fcac.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fad48828fcac.png?mw=700" alt="image.png" /></a><br /> 動作確認もOKでした!</p> <p>おわり*0 v 0</p> same.__.same tag:crieit.net,2005:PublicArticle/16212 2020-11-12T00:09:25+09:00 2020-11-12T00:09:25+09:00 https://crieit.net/posts/2020-11-11 2020.11.11 * 削除機能 <h2 id="本日のゴール"><a href="#%E6%9C%AC%E6%97%A5%E3%81%AE%E3%82%B4%E3%83%BC%E3%83%AB">本日のゴール</a></h2> <p>■ 英単語を削除できるようにする</p> <h2 id="削除アクション"><a href="#%E5%89%8A%E9%99%A4%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3">削除アクション</a></h2> <p>ルーティングを確認するとdestroyアクションはword_pathのDELETEメソッドが割り当てられていました。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fabf0fe995eb.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fabf0fe995eb.png?mw=700" alt="image.png" /></a><br /> なぜ通常のgetルーティングではないのかと言うと、GETメソッドだとhtmlのaタグなどを使って削除を実行するリクエストが簡単に送れてしまうからなのですね。なるほど!! ※<a target="_blank" rel="nofollow noopener" href="https://railsguides.jp/getting_started.html#記事を削除する">Railsガイド</a>より</p> <p>そういえばwordsコントローラを作成するとき<br /> <code>$ rails g controller Words new show edit delete</code><br /> としたため、削除のアクションがdeleteになってました。</p> <pre><code>class WordsController < ApplicationController def new end def create @word = Word.new(word_params) @word.save redirect_to @word end def show @word = Word.find(params[:id]) end def edit end def delete #←これ end private def word_params params.require(:word).permit(:english, :japanese) end end </code></pre> <p>deleteを消してdestroyの中身を書いていきます。<br /> <strong>words_controller.rb</strong></p> <pre><code> def destroy @word = Word.find(params[:id]) @word.destroy redirect_to word_path end </code></pre> <p>リダイレクト先をshow画面にしましたが、このままだと削除した単語を表示する画面に遷移させようとしてエラーになります。<br /> なのでshowは全件表示するように変更します。</p> <pre><code> def show @words = Word.all end </code></pre> <p>これに伴い<strong>show.html.erb</strong>も変更。</p> <pre><code><h1>SHOW</h1> <div> <% @words.each do |word| %> <div> ID: <%= word.id %> | ENGLISH: <%= word.english %> | JAPANESE: <%= word.japanese %> </div> <% end %> </div> </code></pre> <p>こんな感じになりました。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fabfcfaefce5.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fabfcfaefce5.png?mw=700" alt="image.png" /></a></p> <h2 id="削除view"><a href="#%E5%89%8A%E9%99%A4view">削除view</a></h2> <p>どの画面で削除できるようにするかまだ考えていないので、とりあえずshow画面にボタンを置いておきます。<br /> <strong>words/show.html.erb</strong></p> <pre><code><h1>SHOW</h1> <div> <% @words.each do |word| %> <div> ID: <%= word.id %> | ENGLISH: <%= word.english %> | JAPANESE: <%= word.japanese %> <%= button_to 'Delete', word_path(word), method: :delete %> </div> <% end %> </div> </code></pre> <p>コントローラ作成時に作られたwords/delete.html.erbは要らないので削除。<br /> <a href="">http://localhost:3000/words/1</a>にアクセスすると<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fabfd977d817.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fabfd977d817.png?mw=700" alt="image.png" /></a><br /> ボタンが変な所にいますがとりあえず気にしない。</p> <p>id=3のDeleteボタンを押してみます。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fabfe0444c1e.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fabfe0444c1e.png?mw=700" alt="image.png" /></a><br /> word3が消えました✨</p> <h2 id="宿題"><a href="#%E5%AE%BF%E9%A1%8C">宿題</a></h2> <p>全件表示する画面に<a href="">http://localhost:3000/words/1</a>でアクセスするっていうのはおかしいですね。<br /> ちゃんと画面構成考えないと。</p> <p>おわり*0 v 0</p> same.__.same tag:crieit.net,2005:PublicArticle/16208 2020-11-10T17:12:09+09:00 2020-11-10T17:16:26+09:00 https://crieit.net/posts/2020-11-10 2020.11.10 * 英単語の登録機能 <h2 id="本日のゴール"><a href="#%E6%9C%AC%E6%97%A5%E3%81%AE%E3%82%B4%E3%83%BC%E3%83%AB">本日のゴール</a></h2> <p>■ 英単語を登録できるようにする<br /> ■ 登録されたデータを画面で見れるようにする</p> <h2 id="登録用のアクションとviewを作成"><a href="#%E7%99%BB%E9%8C%B2%E7%94%A8%E3%81%AE%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A8view%E3%82%92%E4%BD%9C%E6%88%90">登録用のアクションとviewを作成</a></h2> <p>前回wordsコントローラを作成した際、アクションはnew, show, edit, delete としました。<br /> しかしnewは登録画面を表示する関数なので、「DBに登録する」という処理用のアクションが必要です。<br /> なのでwordコントローラにcreateアクションを追加します。</p> <pre><code>class WordsController < ApplicationController def new end def create @word = Word.new(params.require(:word).permit(:english, :japanese)) @word.save redirect_to @word end def show end def edit end def delete end end </code></pre> <p>処理の意味は以下のとおりです。<br /> 1. フォームに入力された値を引数として受け取り、Wordモデルをインスタンス化<br />   英単語と日本語訳だけ入力する想定なので、許可する引数はenglishとjapaneseのみにしました。<br /> 2. DBに保存<br /> 3. showアクションにリダイレクト</p> <p>viewも実装します。<br /> <strong>new.html.erb</strong></p> <pre><code><%= form_with scope: :word, local:true do |f| %> <div> <%= f.label :english %> <%= f.text_field :english %> </div> <div> <%= f.label :japanese %> <%= f.text_field :japanese %> </div> <%= f.submit %> <% end %> </code></pre> <p><a href="">http://localhost:3000/words/new</a>にアクセスするとこんな画面になりました。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25faa3005ae5ad.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25faa3005ae5ad.png?mw=700" alt="image.png" /></a></p> <p>EnglishとJapaneseを入力してsaveボタンを押してみます。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25faa311198a15.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25faa311198a15.png?mw=700" alt="image.png" /></a><br /> ルーティングエラー・m・<br /> [POST]"/words/create"にしたいのに"words/new"になってしまっていますね。<br /> form_withに:urlオプションを追加しましょう。<br /> 先ほどのエラー画面に表示されたルートを参考にします。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25faa33eaf336c.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25faa33eaf336c.png?mw=700" alt="image.png" /></a></p> <p>words_pathのPOSTがcreateアクションに割り当てられているので、<strong>words_controller.rb</strong>の1行目に<em>url: words_path</em>を追加します。</p> <pre><code><%= form_with scope: :word, url: words_path, local:true do |f| %> </code></pre> <p>で、<a href="">http://localhost:3000/words/new</a>にアクセスしてsaveボタン押下。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25faa36116fc92.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25faa36116fc92.png?mw=700" alt="image.png" /></a><br /> ちゃんとshowアクションにリダイレクトされました!URLは<a href="">http://localhost:3000/words/1</a>となっています。</p> <h2 id="showアクションを実装"><a href="#show%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E5%AE%9F%E8%A3%85">showアクションを実装</a></h2> <p>登録されたデータを画面で確認できるようにします。<br /> まず<strong>words_controller.rb</strong></p> <pre><code>class WordsController < ApplicationController   中略 def show @word = Word.find(params[:id]) end </code></pre> <p>@wordの受け取り先は<strong>show.html.erb</strong>です。</p> <pre><code><h1>SHOW</h1> <div> <p>ENGLISH: <%= @word.english %></p> <p>JAPANESE: <%= @word.japanese %></p> </div> </code></pre> <p>これで先ほどの<a href="">http://localhost:3000/words/1</a>にアクセスしてみます。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25faa44c244515.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25faa44c244515.png?mw=700" alt="image.png" /></a><br /> 無事登録できていました✨</p> <h2 id="パラメータの処理を切り出し"><a href="#%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%81%AE%E5%87%A6%E7%90%86%E3%82%92%E5%88%87%E3%82%8A%E5%87%BA%E3%81%97">パラメータの処理を切り出し</a></h2> <p>パラメータの許可を逐一書くのはよくないので共通化します。<br /> <strong>words_controller.rb</strong></p> <pre><code>class WordsController < ApplicationController   def create @word = Word.new(word_params) @word.save redirect_to @word end private def word_params params.require(:word).permit(:english, :japanese) end end </code></pre> <p>※変更のない部分は割愛しています。<br /> word_paramsという関数を作成し、createの<code>Word.new( )</code>の中で呼び出すようにしました。</p> <h2 id="formをパーシャル化"><a href="#form%E3%82%92%E3%83%91%E3%83%BC%E3%82%B7%E3%83%A3%E3%83%AB%E5%8C%96">formをパーシャル化</a></h2> <p>viewのフォーム部分はnewとeditで共通になるので、パーシャル(部分テンプレート)にして共通化しようと思います。<br /> app/views/words/ディレクトリに<strong>_form.html.erb</strong>というファイルを作成します。命名規則にしたがってプレフィックスにはアンダースコアを付けました。<br /> ここにedit.html.erbの中身を移植します。</p> <pre><code><%= form_with scope: :word, url: words_path, local:true do |f| %> <div> <%= f.label :english %> <%= f.text_field :english %> </div> <div> <%= f.label :japanese %> <%= f.text_field :japanese %> </div> <%= f.submit %> <% end %> </code></pre> <p>そして<strong>edit.html.erb</strong>の方はこれだけに。</p> <pre><code><%= render 'form' %> </code></pre> <p>動作確認もきちんとできました!</p> <p>おわり*0 v 0</p> same.__.same tag:crieit.net,2005:PublicArticle/16207 2020-11-09T19:02:51+09:00 2020-11-10T13:45:20+09:00 https://crieit.net/posts/2-5fa913cb5e444 2020.11.9 * 最初のコントローラとWord・Chapterモデル <h2 id="本日のゴール"><a href="#%E6%9C%AC%E6%97%A5%E3%81%AE%E3%82%B4%E3%83%BC%E3%83%AB">本日のゴール</a></h2> <p>■ コントローラ作成<br /> ■ Wordモデル・Chapterモデル作成</p> <h2 id="全体像を考える"><a href="#%E5%85%A8%E4%BD%93%E5%83%8F%E3%82%92%E8%80%83%E3%81%88%E3%82%8B">全体像を考える</a></h2> <p>まずはシンプルに作っていこうと思います。<br /> 実装したい機能は以下の通り。<br /> * 英単語とその日本語訳を登録することができる<br /> * 登録した英単語は編集、削除もできる<br /> * 30語くらいの単位で章分けする<br /> * 章ごとに小テスト(英単語が表示され、その日本語訳を答える)が作られる<br /> * 小テストが採点される<br /> * 間違えた問題を集めた再テストが作られる</p> <h2 id="最初のコントローラ"><a href="#%E6%9C%80%E5%88%9D%E3%81%AE%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%A9">最初のコントローラ</a></h2> <p>TOP画面を作ります。まだモデルは関連しないのでコントローラを作成。<br /> <code>$ rails g controller Top index</code><br /> Topコントローラにindexというアクションを作りました。</p> <p>サーバを起動してhttp://localhost:3000/top/indexにアクセスすると画面が表示されます。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fa8db532c7cb.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fa8db532c7cb.png?mw=700" alt="image.png" /></a></p> <p>これをトップ画面にしたいので、http://localhost:3000でアクセスできるようにルーティングを変更します<br /> <strong>routes.rb</strong>に<code>root 'top#index'</code>を追加</p> <pre><code>Rails.application.routes.draw do root 'top#index' get 'top/index' # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html end </code></pre> <p>「ルートURLはTopコントローラのindexアクションです」という意味ですね。これで完了です!</p> <p>TOP画面をどうするかは未定なのですが、とりあえずwelcomeな感じにしておきます。<br /> 先ほどの<code>$ rails g</code>コマンドで作成された<strong>index.html.erb</strong>ファイルを編集します。</p> <pre><code><h1>*WELCOME*</h1> <p>take it easy! 0 v 0</p> </code></pre> <p><a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fa8e20d7d600.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fa8e20d7d600.png?mw=700" alt="image.png" /></a></p> <h2 id="WordモデルとChapterモデル"><a href="#Word%E3%83%A2%E3%83%87%E3%83%AB%E3%81%A8Chapter%E3%83%A2%E3%83%87%E3%83%AB">WordモデルとChapterモデル</a></h2> <p>次に英単語モデルとチャプターモデルを作ります。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fa8fe2e4b180.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fa8fe2e4b180.png?mw=700" alt="image.png" /></a></p> <p>wordモデルとchapterモデルを仮で作成します。<br /> 主キーのidは自動で追加されるのでここでは明記しません。また、wordモデルのchapter_idも抜いておきます。<br /> <code>$ rails g model Word english:string japanese:string should_retest:boolean</code><br /> <code>$ rails g model Chapter name:string</code><br /> これでマイグレーションファイルが2つ作られました。</p> <p>chapter : word = 1 : n にしたいので、wordの方のマイグレーションファイル<strong>20201109_create_words.rb</strong>に<code>t.references :chapter, foreign_key: true</code>を追記します。</p> <pre><code>class CreateWords < ActiveRecord::Migration[6.0] def change create_table :words do |t| t.string :english t.string :japanese t.boolean :should_retest t.references :chapter, foreign_key: true # ←ここを追記 t.timestamps end end end </code></pre> <p>DBに反映させます。<br /> <code>$ rails db:migrate</code></p> <pre><code>== 20201109093357 CreateWords: migrating ====================================== -- create_table(:words) -> 0.0140s == 20201109093357 CreateWords: migrated (0.0141s) ============================= == 20201109093405 CreateChapters: migrating =================================== -- create_table(:chapters) -> 0.0029s == 20201109093405 CreateChapters: migrated (0.0029s) ========================== </code></pre> <p>コマンドで確認してみます。<br /> <code>$ sqlite3 db/development.sqlite3</code><br /> <code>sqlite> .tables</code></p> <pre><code>ar_internal_metadata schema_migrations chapters words </code></pre> <p>chaptersとwordsというテーブルが作成されています。</p> <p>wordsのカラムを確認すると<br /> <code>sqlite> PRAGMA table_info(words);</code></p> <pre><code>cid|name|type|notnull|dflt_value|pk 0|id|integer|1||1 1|english|varchar|0||0 2|japanese|varchar|0||0 3|should_retest|boolean|0||0 4|chapter_id|integer|0||0 5|created_at|datetime(6)|1||0 6|updated_at|datetime(6)|1||0 </code></pre> <p>先ほど主キーのidとchapter_idはマイグレーションファイルに記載していなかったのですが、ちゃんと作成されています。chapter_idは<strong>t.references :chapter, foreign_key: true</strong>を追加したおかげで自動作成されたんですね。</p> <h2 id="Wordコントローラ"><a href="#Word%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%A9">Wordコントローラ</a></h2> <p>モデルができたので、CRUD(Create, Read, Update, Delete)を定義するコントローラを作成します。<br /> 命名規則にしたがってwordは複数形に。<br /> <code>$ rails g controller Words new show edit delete</code><br /> <strong>words_controller.rb</strong></p> <pre><code>class WordsController < ApplicationController def new end def show end def edit end def delete end end </code></pre> <p>4つ分のhtml.erbも作成されました。もしかしたらdelete.html.erbは要らないかもな</p> <h2 id="ルーティング"><a href="#%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0">ルーティング</a></h2> <p>wordコントローラを作成した際にルーティングも↓こんな風に反映されましたが、<br /> <strong>routes.rb</strong></p> <pre><code>Rails.application.routes.draw do get 'words/new' get 'words/show' get 'words/edit' get 'words/delete' root 'top#index' get 'top/index' # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html end </code></pre> <p>resourceメソッドを使えばCRUDのルーティングをまとめて定義することができます。<br /> <strong>routes.rb</strong></p> <pre><code>Rails.application.routes.draw do root 'top#index' get 'top/index' resources :words # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html end </code></pre> <p>これで、たとえばnew画面にはhttp://localhost:3000/words/newでアクセスできるようになりました。<br /> <a href="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fa913b76aaaa.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bc26d865acd6cc517615f2588057bac25fa913b76aaaa.png?mw=700" alt="image.png" /></a></p> <p>本当はCRUDの処理も書きたかったですが時間切れです!</p> <p>おわり*0 v 0</p> same.__.same tag:crieit.net,2005:PublicArticle/16205 2020-11-06T18:26:29+09:00 2020-11-10T13:44:48+09:00 https://crieit.net/posts/Ruby-on-Rails-web 2020.11.6 * サーバ起動まで <h2 id="本日のゴール"><a href="#%E6%9C%AC%E6%97%A5%E3%81%AE%E3%82%B4%E3%83%BC%E3%83%AB">本日のゴール</a></h2> <p>■ アプリケーション作成<br /> ■ $ rails s でlocalhost:3000にアクセス</p> <h2 id="アプリ作成"><a href="#%E3%82%A2%E3%83%97%E3%83%AA%E4%BD%9C%E6%88%90">アプリ作成</a></h2> <p>まずはアプリ作成<br /> <code>$ rails new words_app</code><br /> Gemをインストール<br /> <code>$ bundle update</code><br /> <code>$ bundle install</code></p> <h2 id="サーバ起動までのエラーを解消"><a href="#%E3%82%B5%E3%83%BC%E3%83%90%E8%B5%B7%E5%8B%95%E3%81%BE%E3%81%A7%E3%81%AE%E3%82%A8%E3%83%A9%E3%83%BC%E3%82%92%E8%A7%A3%E6%B6%88">サーバ起動までのエラーを解消</a></h2> <p>アプリのディレクトリに移動してサーバ起動!<br /> <code>$ cd words_app</code><br /> <code>$ rails s</code></p> <p>エラーになってしまった.__.<br /> ログを取るのを忘れてしまったのですが</p> <pre><code>rescue in load': Webpacker configuration file not found Please run rails webpacker:install </code></pre> <p>みたいな感じでした。</p> <p>言われた通りに<br /> <code>$ rails webpacker:install</code><br /> したら</p> <pre><code>Yarn not installed. Please download and install Yarn from https://yarnpkg.com/lang/en/docs/install/ </code></pre> <p>yarnがインストールされていないと。Homebrewでインストールします!<br /> <code>$ brew install yarn</code></p> <p>インストールしてるっぽいログがたくさん出力されたので確認!<br /> <code>$ yarn -v</code></p> <pre><code>zsh: command not found: yarn </code></pre> <p>できてなかった!</p> <p>いっぱい出てきたログの中に↓こう書いてあったので</p> <pre><code>Error: yarn 1.22.0 is already installed To upgrade to 1.22.10, run `brew upgrade yarn`. </code></pre> <p>upgradeします<br /> <code>$ brew upgrade yarn</code></p> <p>いけたっぽいので確認<br /> <code>$ yarn -v</code></p> <pre><code>1.22.10 </code></pre> <p>やったー!</p> <p>本題に戻ってwebpackerを入れます<br /> <code>$ rails webpacker:install</code></p> <p>長ーいログが出て</p> <pre><code>Webpacker successfully installed 🎉 🍰 </code></pre> <p>だそうです。わーい!</p> <p>最後に<br /> <code>$ rails s</code><br /> で起動できました✨<br /> <a href="https://crieit.now.sh/upload_images/68542a09352711ec4109a75b73c96eb55fa515ab00a1a.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/68542a09352711ec4109a75b73c96eb55fa515ab00a1a.png?mw=700" alt="rails.png" /></a></p> <p>おわり*0v0</p> same.__.same