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から新規作成してその後編集してみてください

きっちり動作してますね

次回、完成

今回はここまで

お疲れさまでした

いよいよアプリ制作も終盤

次回で完成です!

絶対に挫折しないRailsアプリ制作05

コメントを残す

メールアドレスが公開されることはありません。

Rating

wp-puzzle.com logo