Content一覧を表示する
ではindex.html.erbに保存したContentを表示してみましょう
まずはコントローラーのindexメソッドにこう記述
コード
これは@contentsに保存されたすべてのContentを持ってきてと指示しています
今は一つですが保存されたContentは将来的に複数あるので@contentsと複数形にします
ではindex.html.erbを作って行きます
<% @contents.each do |content| %>
<div class='memos row'>
<div class='col-sm-6'>
<%= link_to content_path(content) do %>
<%= content.title %>
<% end %>
</div>
<div class='col-sm-3'>
<%= content.updated_at.strftime("%Y-%m-%d %H:%M") %>
</div>
<div class='col-sm-3'>
<%=link_to '削除', '#', class: 'btn-delete btn btn-danger' %>
</div>
<hr class='line'>
</div>
<% end %>
divとかはデザインに使っているだけですのでRubyの部分に注目してください
@contentsに入ってるContentをeach文で取り出しています
今回取り出したい要素は
- タイトル
- 更新日時
<%= link_to content_path(content) do %>
<%= content.title %>
<% end %>
ここのcontenet.titleでContentのタイトルを表示しています
link_toはこのタイトルにリンクを貼っています
どんなリンクかというと詳細画面です
引数でIDを判別しています
クリックされたタイトルのIDを取得してそのIDの詳細画面に飛ばす
といった命令です
削除ボタンはまだ削除機能を実装してないのでリンクは「#」と適当なものにしています
さてサーバーを再起動して実行
このようになっていたらOK
そしてタイトルを押した時にURLがcontents/1/に行っていたら成功ですね
とりあえずcontens/数字 になっていたらOK
show.htmlはまだ作り込んでいないので特にContentの詳細はまだ表示されません
詳細画面を表示する
まずはコントローラーのshowメソッドをこのように
def show
@content = Content.find(params[:id])
end
では解説します
詳細を表示するにはContentのIDが必要です
「ID5番のContentを見せて」という感じに指示しないとコントローラーが
「え?どのContent??」ってなるからです
@content = Content.find(params[:id])
先程show.html.erbのURLを見た時に「contents/1」といった具合に最後にIDが表示されてましたね
そのIDのContentを見つけて@contentに代入しています
「contents/1」で言うのであればID1のContentの内容を@contentが所持しています
ではこの@contentを使って詳細を表示していきます
show.html.erbを編集していきます
<h1>詳細ページ</h1>
<div class='contentParts'>
<h2><%= @content.title %></h2>
</div>
<div class='contentParts'>
<%= image_tag @content.image.url if @content.image? %>
</div>
<div class='contentParts'>
<%= @content.body %>
</div>
<div class='contentParts'>
<%=link_to "編集", '#', class: 'btn btn-success' %>
<%=link_to "削除", '#', class: 'btn-delete btn btn-danger' %>
</div>
また「contents/1」の場合で見ていきます
@content.title
はContentのID1のtitleということになります
<%= image_tag @content.image.url if @content.image? %>
ここで保存した画像をurl化して表示させようとしています
ifは「もし画像があれば表示してね〜」ってことです
画像なしでContentを登録したらここはskipされます
ではサーバーを再起動してindex.html.erbから詳細をクリックしてみましょう
ごめんね、エラーが出ちゃった
実行したらこうなりました?
これは申し訳ない
謝りますから絶対許してください
画像が無いのに呼び出すな!
って怒られちゃいました
ではちゃんと表示できるようにしましょう
gemでcarrierwaveをインストールしたのは覚えてますか?
これを使ってますのでこの設定を行います
まずはターミナルで
$ rails g uploader image
とします
今回はデータベースに画像を登録する時にimageというカラム名にしています
ですから最後が「image」
もしも画像を登録するカラム名を「img」にしていたら
$ rails g uploader img
になります
app/models/content.rbに下記を追加
class Content < ApplicationRecord
# これを追加
mount_uploader :image, ImageUploader
end
では一度サーバーを再起動して新規投稿してみましょう
その際に画像も登録してください
しっかり画像も表示されていたらOK
ちょっと補足!
<%= @content.body %>
これは特に間違えてるわけではないですが理想的ではないです
テキストエリアに書き込まれたContentのbodyですが改行したい時もありますよね?
これだと表示する時に改行されずに表示されてしまいます
これを防ぐためにはコードをこのようにします
<%= safe_join(@content.body.split("\n"),tag(:br)) %>
これでOKにです
編集機能を実装
次は編集機能を作っていきます
まずはコントローラーのeditメソッドから
def edit
@content = Content.find(params[:id])
end
はい、showメソッドと一緒ですね
どのContentを編集するか判別するためにまたContentのIDを@contentに代入するといった具合です
そしてここからがshowメソッドと違います
IDを取得してedit.html.erbで編集したあとは内容を更新しないといけません
そこでupdateメソッドを記述します
def update
@content = Content.find(params[:id])
@content.update(content_params)
redirect_to content_path(@content)
end
これはcreateメソッドと似ていますね
@content.update(content_params)
で更新です
リダイレクトで編集したContentの詳細画面へ飛ばしています
ではedit.html.erbを作り込みます
<h1>編集画面</h1>
<%= form_with model:@content do |f| %>
<div class='formGroup'>
<%= f.text_field :title, class: 'form-control', placeholder: 'メモタイトル' %>
</div>
<div class='formGroup'>
<%= f.file_field :image, class: 'form-control' %>
</div>
<div class='formGroup'>
<%= f.text_area :body, class: 'form-control', placeholder: 'メモ本文' %>
</div>
<div class='formGroup'>
<%= f.submit '保存', class: 'btn btn-primary' %>
</div>
<% end %>
はい、new.html.erbと<h1>以外一緒です
new.html.erbをコピペでいいです
次は先程作ったshow.html.erbの編集ボタンにリンクを付けます
編集画面に飛ぶリンクは
edit_content_pathですね
これだとどの編集画面に飛んでいいのかわからないので引数に@contentをつけてあげましょう
<%=link_to "編集", edit_content_path(@content), class: 'btn btn-success' %>
ではサーバーを再起動して確認しましょう
なにか新規投稿するか既にあるContentをクリックしてください
編集画面に飛んで編集したら「保存」をクリック
編集した内容になっていたらOKです
無駄をなくそう
結構いいところまで進んで来ましたね
ここで少しコードをスッキリさせます
new.html.erbとedit.html.erbですが<h1>以外は全部いっしょですよね?
この状態だとnew.html.erbをなにか編集した時にedit.html.erbも編集しないといけません
するとミスであったり忘れたりすることがあるので一つにまとめてしまいます
app/views/contentsフォルダに新たなファイルを追加します
「_form.html.erb」
を作ってください
共通化するときのファイル名は頭に「_」をつけるのが決まりです
中身はnew.html.erbでもedit.html.erbでもいいので<h1>より下のform_withからendまでをコピペして保存してください
続いてnew.html.erbとedit.html.erbを編集します
<h1>より下のform_withからendまで全部消して<h1>の下にこれを追加
<%= render partial: 'form' %>
これで「_form.html.erb」を読み込んでくれます
この時「_」と「.html.erb」は書かなくて大丈夫です
保存してサーバーを再起動してください
contents/newから新規作成してその後編集してみてください
きっちり動作してますね
次回、完成
今回はここまで
お疲れさまでした
いよいよアプリ制作も終盤
次回で完成です!