詳細ページ・削除・編集機能の実装
初めましてこんにちは!すんぎぃです。
SoundReviewというアプリができるまでの流れをやっています。
今回は、詳細ページ・削除・編集機能の実装方法について話していきます。
1.目的
投稿の詳細を見ることができるようにする。
投稿をした人が投稿を取り消したり、内容を変更できるようにする。
2.扱うgem
なし
3.方法
○詳細ページ作成
①routesを以下のように編集します。
Rails.application.routes.draw do
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
devise_for :users
root to: 'items#index'
resources :items ,only: [:index,:new,:create,:show]
ends
詳細ページの作成のためshowアクションを追加します。
②投稿一覧ページから詳細ページに遷移できるようにします。
index.html.erbを以下のように編集します。
//省略
<li class='list'>
<%= link_to item_path(item.id),class:"link" do %>
<div class='item-info'>
<%= item.name%>
</div>
//省略
<%end%>
<li>
パスは、terminalで以下のようにすることで見ることができます。
% rails routes
詳細表示するものを区別するために、パスにはitemのidをパラメーターとして持たせています。
③showアクションをコントローラーに定義していきます。
以下のようにitemsコントローラーにshowアクションを定義します。
class ItemsController < ApplicationController
before_action :authenticate_user!, except: [:index, :show]
before_action :set_item, only: [:show]
//省略
def show
end
private
def item_params
params.require(:item).permit(:name, :text, :audio, :category_id, :url, :image, :minicategory).merge(user_id: current_user.id)
end
def set_item
@item = Item.find(params[:id])
end
end
パラメータとして受け取ったparams[:id]をもとに、詳細表示したいitemをfindメソッドを用いて取得しています。
④詳細ページの作成をしていきます。
app/views/itemsディレクトリにビューファイルにshow.html.erbを作成します。
⑤show.html.erbを以下のように編集します。
<%= render "shared/header" %>
<div class="item-show">
<div class="item-box">
<div class="item-profile">
<div class="cate-name">
<span class="show-category">Category</span><br/>
<%if @item.category.name== "映画" %>
<%= link_to "#{@item.category.name}", "/” ,class: "another-itom" %><br/><p class="mini-name"><%=@item.minicategory%><p>
<%elsif @item.category.name== "アニメ" %>
<%= link_to "#{@item.category.name}", "/" ,class: "another-itom" %><br/><p class="mini-name"><%=@item.minicategory%><p>
<%elsif @item.category.name== "音楽" %>
<%= link_to "#{@item.category.name}", "/" ,class: "another-itom" %><br/><p class="mini-name"><%=@item.minicategory%><p>
<%elsif @item.category.name== "本" %>
<%= link_to "#{@item.category.name}", "/" ,class: "another-itom" %><br/><p class="mini-name"><%=@item.minicategory%><p>
<%elsif @item.category.name== "その他" %>
<%= link_to "#{@item.category.name}", "/" ,class: "another-itom" %><br/><p class="mini-name"><%=@item.minicategory%><p>
<%end%>
</div>
</div>
<h2 class="name">
<%= @item.name %>
</h2>
<div class="item-content">
<div class="item-img-content">
<%if @item.image.attached? %>
<%= image_tag @item.image, class: "item-box-img" %>
<%else%>
<%= image_tag 'soundreview2.png', class: "item-box-img" %>
<%end%>
</div>
</div>
<div class="item-user">
<div class="profile">
<% if @item.user.image.attached? %>
<%=link_to "/",class:"user-icon4" do %>
<%= image_tag @item.user.image, class: "user-icon4" %>
<%end%>
<% else %>
<%=link_to "/" ,class:"user-icon4" do %>
<%= image_tag "willy.png", alt: "user-icon", class: "user-icon4" %>
<%end%>
<% end %>
</div>
<div class="item-user-name">
<%= link_to @item.user.nickname, "/" %>
</div> <br/>
</div>
<div>
<%=@item.created_at.strftime('%Y/%m/%d')%>
</div>
<div class="item-price-box">
<audio src= "<%= "#{@item.audio}" %>" controls="" preload="metadata">
</audio>
</div>
<%if @item.text.present?%>
<table class="detail-table">
<tbody>
<tr>
<th class="detail-item">テキストレビュー</th>
<td class="detail-value detail-text" id="text"><%= @item.text %></td>
</tr>
</tbody>
</table>
<%end%>
<%if @item.url.present?%>
<div class="url">
外部URL<br/>
<div class="item-urll">
<%=link_to "関連サイトへ", @item.url %>
</div>
</div>
<%end%>
</div>
<%if @item.category.name== "映画" %>
<%= link_to "#{@item.category.name}をもっと見る", "/" ,class: "another-item" %>
<%elsif @item.category.name== "アニメ" %>
<%= link_to "#{@item.category.name}をもっと見る", "/" ,class: "another-item" %>
<%elsif @item.category.name== "音楽" %>
<%= link_to "#{@item.category.name}をもっと見る", "/" ,class: "another-item" %>
<%elsif @item.category.name== "本" %>
<%= link_to "#{@item.category.name}をもっと見る", "/" ,class: "another-item" %>
<%elsif @item.category.name== "その他" %>
<%= link_to "#{@item.category.name}をもっと見る", "/" ,class: "another-item" %>
<%end%>
</div>
<%= render "shared/footer" %>
これで詳細ページを表示することができます。
○編集機能の実装
①routesを以下のように編集します。
Rails.application.routes.draw do
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
devise_for :users
root to: 'items#index'
resources :items ,only: [:index,:new,:create,:show,:edit]
end
編集機能を実装するためにshowアクションを加えていきます。
②詳細ページから編集ページに遷移できるようにします。
show.html.erbを以下のように編集します。
//省略
<%if @item.url.present?%>
<div class="url">
外部URL<br/>
<div class="item-urll">
<%=link_to "関連サイトへ", @item.url %>
</div>
</div>
<%end%>
<%if user_signed_in?%>
<%if current_user.id==@item.user_id %>
<div class="edit-btn">
<div class="edit">
<%= link_to "レビューの編集", edit_item_path, method: :get, class: "item-red-btn" %>
</div>
</div>
<%end%>
<%end%>
//省略
③editアクションをコントローラーに定義していきます。
以下のようにitemsコントローラーにeditアクションを定義します。
class ItemsController < ApplicationController
before_action :authenticate_user!, except: [:index, :show]
before_action :set_item, only: [:show,:edit]
//省略
def edit
end
private
def item_params
params.require(:item).permit(:name, :text, :audio, :category_id, :url, :image, :minicategory).merge(user_id: current_user.id)
end
def set_item
@item = Item.find(params[:id])
end
end
④編集ページの作成をしていきます。
app/views/itemsディレクトリにビューファイルにedit.html.erbを作成します。
⑤edit.html.erbを以下のように編集します。
<div class="items-sell-contents">
<header class="items-sell-header">
<%= link_to image_tag('soundreview.png' , size: '185x50'), "/" %>
</header>
<div class="items-sell-main">
<h2 class="items-sell-title">レビューの情報を入力</h2>
<%= render 'shared/error_messages', model: @item %>
<%= form_with model:@item, local: true do |f| %>
<div class="items-detail">
<div class="weight-bold-text">
カテゴリー
<span class="indispensable">*必須</span>
</div>
<div class="form">
<%= f.collection_select(:category_id, Category.all, :id, :name, {}, {class:"select-box", id:"item-category"}) %>
</div>
<div class="new-items">
<div class="weight-bold-text">
サブカテゴリー
</div>
<%= f.text_area :minicategory, class:"items-text", id:"item-name" %>
</div>
</div>
<div class="img-upload">
<div class="weight-bold-text">
レビュー画像
</div>
<div class="click-upload">
<p>
クリックしてファイルをアップロード
</p>
<%= f.file_field :image, id:"item-image" %>
</div>
</div>
<div class="new-items">
<div class="weight-bold-text">
作品名<span class="counter">(40文字まで)</span>
<span class="indispensable">*必須</span>
</div>
<%= f.text_area :name, class:"items-text", id:"item-name" %>
</div>
<div class="sound-upload">
<div class="weight-bold-text">
音声レビュー
<span class="indispensable">*必須</span>
</div>
<div class="click-upload">
<p>
クリックしてファイルをアップロード
</p>
<%= f.file_field :audio, id:"item-sound" %>
</div>
</div>
<div class="new-items">
<div class="items-explain">
<div class="weight-bold-text">
文字レビュー
</div>
<%= f.text_area :text, class:"items-text", id:"item-info"%>
</div>
</div>
<div class="item-url">
<div class="weight-bold-text">
作品URL
</div>
<%= f.text_area :url, class:"url", id:"item-name",class:"url" %>
</div>
<div class="sell-btn-contents">
<%= f.submit "投稿する" ,class:"sell-btn" %>
<%=link_to 'もどる', item_path(@item.id), class:"back-btn" %>
</div>
</div>
<% end %>
<footer class="items-sell-footer">
<%= link_to image_tag('soundreview.png' , size: '185x50'), "/" %>
<p class="inc">
©︎SoundReview,Inc.
</p>
</footer>
</div>
⑥updateアクションのルーティングを設定します。
routesを以下のように編集します。
Rails.application.routes.draw do
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
devise_for :users
root to: 'items#index'
resources :items ,only: [:index,:new,:create,:show,:edit,:update]
end
更新をしたいのでupdateアクションを追加します。
terminalでrails routesを行い確認すると投稿内容などの部分的な更新をするので、updateアクションにはPATCHというHTTPメソッドが使用されます。
⑦updateアクションをコントローラーに定義していきます。
以下のようにitemsコントローラーにupdateアクションを定義します。
class ItemsController < ApplicationController
before_action :authenticate_user!, except: [:index, :show]
before_action :set_item, only: [:show,:edit,:update]
//省略
def update
if @item.update(item_params)
redirect_to item_path(@item.id)
else
render :edit
end
end
private
def item_params
params.require(:item).permit(:name, :text, :audio, :category_id, :url, :image, :minicategory).merge(user_id: current_user.id)
end
def set_item
@item = Item.find(params[:id])
end
end
これで実際に編集をすることができるようになりました。
○削除機能の実装
①destroyアクションのルーティングを設定します。
routesを以下のように編集します。
Rails.application.routes.draw do
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
devise_for :users
root to: 'items#index'
resources :items ,only: [:index,:new,:create,:show,:edit,:update,:destroy]
end
resourcesは、7つのアクションをまとめてルーティングの設定ができるので7つのアクションすべてを記述した今、only以下は不要になりました。
そのため以下のように編集することができます。
Rails.application.routes.draw do
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
devise_for :users
root to: 'items#index'
resources :items
end
②詳細ページから投稿を削除できるようにします。
show.html.erbを以下のように編集します。
//省略
<%if @item.url.present?%>
<div class="url">
外部URL<br/>
<div class="item-urll">
<%=link_to "関連サイトへ", @item.url %>
</div>
</div>
<%end%>
<%if user_signed_in?%>
<%if current_user.id==@item.user_id %>
<div class="edit-btn">
<div class="edit">
<%= link_to "レビューの編集", edit_item_path, method: :get, class: "item-red-btn" %>
</div>
<div class="delete">
<%= link_to "削除", item_path, method: :delete, class:"item-destroy" %>
</div>
</div>
<%end%>
<%end%>
//省略
削除するものを区別するために、削除ボタンのパスにはitemのidをパラメーターとして持たせています。
HTTPメソッドは、DELETEというHTTPメソッドを指定しています。
③destroyアクションをコントローラーに定義していきます。
以下のようにitemsコントローラーにdestroyアクションを定義します。
class ItemsController < ApplicationController
before_action :authenticate_user!, except: [:index, :show]
before_action :set_item, only: [:show,:edit,:update,:destroy]
//省略
def destroy
@item.destroy
redirect_to root_path
end
private
def item_params
params.require(:item).permit(:name, :text, :audio, :category_id, :url, :image, :minicategory).merge(user_id: current_user.id)
end
def set_item
@item = Item.find(params[:id])
end
end
パラメーターで受け取ったparams[:id]を元に削除したいitemをfindメソッドを用いて取得しています。そして、そのitemをdestroyメソッドで削除します。
これで削除機能は、完成です。
○cssファイルの追加
app/assets/stylesheets/shared以下にファイルを配置します。
4.まとめ
以上で詳細ページ・削除・編集機能の実装は、完成です。
少しだけ違いますが以下のように表示されたらOK!です。
ありがとうございました。
5.過去記事
この記事が気に入ったらサポートをしてみませんか?