ここまで学んだ知識を使ってTO DOアプリを作成してみましょう。基本のCRUD処理のおさらいにもなります。
自分のやるべきタスクを管理することができるTO DOアプリを作ってみましょう。
イメージとしてはこのようにTO DOリスト一覧のページと、TO DO項目作成&表示ができるページを作ります。
まずはTO DOアプリを開発する為に専用のWorkspaceを作成し、自分なりにアプリを作ってみましょう。
突然アプリを作りなさいと言われても何から始めて良いのかわからない方も多いと思います。
まずはどのような項目が必要なのか設計図を作成します。
これをデータ設計と呼びます。
まずはTO DOリスト一覧が表示されるページのデータ設計を行います。
図のように、TO DOリスト一覧に表示されているのは大まかにリストのタイトル(1.今日の買い物など)と、概要(今日の買い物リストですなど)です。
そこで、リスト一覧ページにはnameとdescriptionというデータが必要であることがわかります。
同様に項目作成&表示ページもデータ設計を考えてみましょう。
こちらは各リストの詳細が表示されるページです。
body(本文)のデータが必要であることがわかります。
この時点では各ページの作成に必要なデータの種類がわかれば良いので、editやdelete、他のページへのリンクなどはデータ設計の際は無視しても大丈夫です。
Workspaceでto_doアプリを作成しましょう。
blogアプリと同様に$ rails new to_doでアプリが作成されます。
では次に先ほどのデータ設計を基に必要なモデルを作成します。
$ rails g model List name:string description:text
モデルを作成したら、必ずマイグレーションを実行します。
$ rake db:migrate
これで必要なデータテーブルが作成されました。
次にroutesファイルを開いてください。
ここでroutesに何のデータをもとにするかを宣言し、必要なHTTPメソッドを作ってもらいます。
resources: lists
と追記して保存します。
$ rake routesで確認すると、各アクションへのパスが作成されていることがわかります。
では次にモデル(データ)と連携する為のコントローラを作成します。
$ rails g controller lists
ここで注意しなければいけないのはRailsの命名ルールです。
モデル→単数系
コントローラ→複数形
でしたね。
コントローラができたので、各アクションに対応したviewファイルも作成しておきましょう。
今回のアプリ開発で必要なviewファイルはどのようなものがあるでしょうか。
リストを新しく投稿するページ(new.html.erb)とリスト詳細の表示(show.html.erb)、リスト一覧表示(index.html.erb)は必要ですね。
各ファイルを作成しておきましょう。
新しくリストを作成するnewアクションを追加しましょう。
listsコントローラのファイルを開いてください。
以下のようにnewアクションを追加して保存します。
def new
@list = List.new
end
これで、@listというインスタンス変数を定義できているためviewファイルで@listが使用できます。
ではnew.html.erbのviewファイルに新規リスト投稿用のフォームを作成していきましょう。
new.html.erbファイルに以下のフォームのコードを追加して保存してください。
<%= form_for @list do |form| %>
<%= form.text_field :name %>
<%= form.text_area :description %>
<%= form.submit %>
<% end %>
$rake routesで確認すると、new.html.erbのパスはnew_lists_pathだとわかります。
ブラウザを更新してみましょう。
投稿用のフォーム部分はできていますが、これではあまりにも不親切です。
どちらのフォームがname、descriptionなのかラベルを追加します。
また、フォームが横並びになっているのもページの表示としては見づらい為マークアップで整えましょう。
以下のラベルと、
タグを追加して保存してください。
<h1>List作成</h1>
<%= form_with scope: :list,url:lists_path,local:true do |form| %>
<p><%= form.label:name %></p>
<p><%= form.text_field :name %></p>
<p><%= form.label:description %></p>
<p><%= form.text_area :description %></p>
<P><%= form.submit %></P>
<% end %>
ブラウザを更新してみましょう。
投稿ページが見やすくなりました!
blogアプリ作成の際に、newアクションで作成したデータは送信ボタンを押すとcreateアクションに飛ばされているということを確認しました。今回も流れは同じです。
![file](https://popshub.s3.amazonaws.com/uploads/ckeditor/pictures/733/content_image-1548373106148.png) newアクションから飛んできたデータをcreateアクションで保存しなければいけません。 newアクションからどのようなデータが飛んできているかを確認しましょう。def create
raise params.inspect
end
ここで"list"=>{"name"=>"テスト","description"=>"データの飛び方"}とありますね。これがCreate Listボタンを押したときに送られているパラメータの中身です。
listsコントローラのcreateアクションに以下のコードを追加してください。
def create
@list = List.new(params[:list])
@list.save
redirect_to list_path(@liset)
end
createアクションに飛んだデータは@list.saveで保存されます。次のredirect_toで保存した後はshow.html.erbへ飛ぶように指示をしています。
コードを保存したら、新規投稿ページにブラウザの戻るボタンをつかって戻り、再度送信ボタンを押します。
エラーになってしましいました。
これは送られてきたデータをそのまま信用してはいけない!というRailsのストロングパラメーターズという機能が働いている為です。
blogアプリと同様にnameとdescriptionのデータは許可されており、必要だとlistコントローラへ明記しましょう。
def list_params
params.require(:list).permit(:name, :description)
end
ここで
params.require(:list).permit(:name, :description)
というコードをとくくりだしているので、createアクションの
@list = List.new(params[:list])
というコードの(params[:list])というパラメータから送られてきたデータ部分を list_paramsと置き換えます。
新規リスト作成の画面へ戻り新しくリストを追加して、送信してください。
何も表示されていません。これは詳細画面であるshow.html.erbに何のコードもないからです。
リストコントローラにshowアクションを追加し、show.html.erbにもコードを追加しましょう。コードは以下の通りです。
lists_controller.rb
def show
@list = List.find(list_params)
end
shotw.html.erb
<h2><%= @list.name %></h2>
<p><%= @list.description %></P>
リスト詳細画面へ遷移することができました!
作成したリストを一覧表示できるようにindexアクションを追加します。 listコントローラに以下を追加してください。
def index
@lists = List.all
end
一覧画面では登録した全てのリストのデータを表示するのでList.allで取得したデータを@listというインスタンス変数に代入しています。 しかし、アクションの追加だけでは一覧を表示することはできません。 ページの表示を担っているviewファイルに一覧を表示するようにコードを追加します。
一覧表示は取得したリストのデータを表示する必要があります。ここで必要な処理はループ処理です。
配列.each do|変数|
繰り返したい処理
end
に当てはめてみると、
@lists.each do|list|
nameの表示
descriptionの表示
end
となります。
@listsに代入されている全てのデータから、全てのnameデータを取得して、詳細画面(show.html.erb)へのリンクを作りましょう。まずはnameデータとdescriptionデータを表示させましょう。そこで最終的な繰り返し処理のコードは
<% @lists.each do |list| %>
<%=@lists.name %>
<%=@lists.description %>
<% end %>
となります。 さらに表示されたnameにshow.html.erbへのリンクを作成します。
<% @lists.each do |list| %>
<li><%= link_to @lists.name,list_path(list) %></li>
<% end %>
rake routesで確認するとindexアクションのURIパターンは/listsです。
一覧画面を表示してみます。
ループ処理が実行され、きちんとリストの全てが表示されています。
リストの編集や、削除ができるようにeditアクションとdestroyアクションを追加します。 リスト一覧で表示されている各リストをeditとdestroyができるようにしてみましょう。
index.html.erbファイルを開いてください。 現在のコードは下記のようになっているはずです。
<h1>Lists一覧</h1>
<% @lists.each do |list| %>
<li><%= link_to @lists.name,list_path(list) %></li>
<% end %>
まずはeditという編集用のリンクを作成します。
<%= link_to '編集する',edhit_list_path(list) %>
を
<h1>Lists一覧</h1>
<% @lists.each do |list| %>
<P><%=list.name %></P>
<% end %>
に追加します。
blogアプリでも解説したように、
<%= link_to '編集する',edhit_list_path(list) %>
の(list)部分は
<% @lists.each do |list| %>
で|list|として渡されている変数です。その為
<% @lists.each do |list| %>~<% end %>
内でしか機能しないという点に注意しましょう。
追加した後のコードは
<h1>Lists一覧</h1>
<% @lists.each do |list| %>
<li><%= link_to @lists.name,list_path(list) %></li>
<%= link_to '編集する',edit_list_path(list) %>
<% end %>
となります。
次に削除用のリンクを作成します。
削除用のリンクは
<p>
<%= link_to'削除する', list_path(list), method: :delete %>
</p>
となります。 ここで注意してほしいのは、rake routesを確認した際、destroyアクションはDELETEメソッドになっているという点です。 HTTPメソッドの中でGET以外はイレギュラー扱いとなる為、メソッドを明記しなければいけません。
そこで
<%= link_to'削除する', list_path(list), method: :delete %>
とコードの中にmethod: :deleteと記述が入っています。では削除用のリンクも追加したコードの全体は下記となります。
<h1>Lists一覧</h1>
<% @lists.each do |list| %>
<p><%= link_to @lists.name,list_path(list) %></p>
<p><%= link_to '編集する',edit_list_path(list) %></p>
<p><%= link_to'削除する', list_path(list), method: :delete %></p>
<% end %>
ではブラウザを更新してください。
編集する、削除するというリンクが完成しています。
編集や削除のリンクは完成しましたが、現在はlistsコントローラにアクションもありませんし、viewファイルの内容もデフォルトのテンプレートのままです。
【コントローラの画像/viewファイルの画像】
まずは編集リンクをクリックしたときに実際にリストの編集を実行できるようにeditアクションを追加しましょう。 listsコントローラを開いてください。
def edit
@list = List.find(params[:id])
end
このeditアクションで該当の(編集したい)リストのデータを[:id]で探して取得します。 教程6で確認したように、editアクションで取得したデータはedit.html.erbファイルの中身として表示されます。 edit.html.erbファイルを開いてください。 編集用の画面にも、投稿用の画面と同じようにnameとdescriptionの編集用のフォームが必要です。 そこでedit.html.erbファイルにもフォームを表示する為、下記のコードを追加します。
<h1>編集する</h1>
<%= form_with(model: @list, local: true)do |form| %>
<p><%= form.text_field :name %></p>
<p><%= form.text_area :description %></p>
<% end %>
form_withの特徴により、@listというインスタンス変数に代入されている値が空ではないと判断し、自動的にupdateアクションへ飛ばしてくれます。 しかし、まだlistsコントローラにはupdateアクションがありませんので、アクションを追加しましょう。 listsコントローラに下記のコードを追加してください。
def update
@list = list.find(params[:id])
if @list.update(list_params)
redirect_to lists_path
else
redirect_to edit_list_path
end
end
updateアクションに送られてきたデータを[:id]の情報から特定します。 そして、もしnameとdescriptionという2つの項目の更新(update)に成功したら、一覧画面に戻りなさい。 そうでなければ、編集画面にとどまりなさい というif~elseの条件分岐のコードとなります。 コントローラファイルとviewファイルにコードを追加し、保存したらブラウザを更新してください。
リストの編集ができるようになりました!
続いてdestroyアクションを追加します。 listsコントローラを開いてください。
def destroy
@list = List.find(params[:id])
@list.destroy
redirect_to lists_path
end
まずは今から削除するリストのデータを取得し、@listというインスタンス変数に代入します。 代入されたデータは@list.destroyで削除されます。 削除が完了したら、リスト一覧画面へ戻るように設定します。 リスト一覧のブラウザを更新してください。
先ほどご自身が選んだリストが削除されていることを確認してください。 先ほどの編集画面と同様に内容が削除されていることを確認してみましょう。
最後にリスト一覧(index.html.erb)、新規リスト作成(new.html.erb)をリンクでつなぎます。
まずはリスト一覧画面に、新規リスト作成画面へのリンクを張りましょう。 index.html.erbファイルに以下のコードを追加して保存してください。
<%= link_to'新規リスト作成',new_list_path %>
次に、新規リスト作成画面からリスト一覧へのリンクを張ります。 new.html.erbファイルに以下のコードを追加してください。
<%= link_to'リスト一覧',lists_path %>
これで2つの画面をリンクでつなぐことができました。
ここまでで、最初にデータ設計をした際のリスト部分は完成です。
次はアイテムを作成します。
無料ビデオ講座のお知らせ
Skillhub [スキルハブ]では無料の動画講座を多数公開しています。他校だと数万円するような講座が無料で受講できます。