#はじめに
エンジニア転職のためポートフォリオを作成しているkazuです。
Railチュートリアルで作った制作物にいいね機能を実装しました!
Railsチュートリアルを一通り終えた方が読者の対象です。
#実装順序
1.ルーティング
2.モデルの設定
3.いいねの表示
4.コントローラの実装
##ルーティング
resources :microposts do
resource :favorites, only: [:create, :destroy]
end
ルーティングは以下のようになります。
micropost_favorites DELETE /microposts/:micropost_id/favorites(.:format) favorites#destroy
POST /microposts/:micropost_id/favorites(.:format) favorites#create
##モデルの設定
###バリデーション
まずはデータベース側の設定、
次にモデルファイルを作ります。
rails g model Favorite user:references micropost:references
「 (モデル名) : references 」を付け足すと、モデルファイルに「belongs_to :micropost」が追加されます。
その結果、user(micropost).favorite といったメソッドチェーンが使えるようになります。
class CreateFavorites < ActiveRecord::Migration[6.0]
def change
create_table :favorites do |t|
t.references :user, null: false, foreign_key: true
t.references :micropost, null: false, foreign_key: true
t.timestamps
end
add_index :favorites, [:user_id, :micropost_id]
end
end
rails db:migrate
マイグレーションファイルをデータベースに反映します。
class Favorite < ApplicationRecord
belongs_to :user
belongs_to :micropost
validates :user_id, presence: true
validates :micropost_id, presence: true
end
モデルのファイルは、こんな感じに。
##いいねボタンの表示
<% if current_user %>
<div>
<h2 class='top-micropost-title'>新着のメニュー</h2>
<div class='top-micropost-wrapper new-wrapper'>
<button id='new-scroll-left' class='scroll-btn new-scroll-btn'> { </button>
<div class='top-micropost white-background slide' >
<%= render partial: 'microposts/micropost', collection: @microposts %>
</div>
<button id='new-scroll-right'class='scroll-btn new-scroll-btn'> } </button>
</div>
</div>
<% end %>
「 render partial: 'microposts/micropost',collection: @microposts」 views/microposts/_micropost.html.erbをレンダリング。
collectionオプションで、配列の要素ごとに部分テンプレートが挿入されます。
今回は@micropostsの要素に対して、パーシャルが呼び出されます。
<li id="micropost-<%= micropost.id %>">
<span class="user"><%= link_to micropost.user.name, micropost.user %></span>
<span class="title"><%= micropost.title %></span>
<span class="content"><%= micropost.content %></span>
<span class="timestamp">
<%= time_ago_in_words(micropost.created_at) %>前
</span>
<div id="favorite_form">
<%if !Favorite.exists?(user_id:current_user.id,post_id:post.id)%>
<p><span><%= micropost.favorites.count %></span>
<%= button_to 'お気に入り登録を削除', micropost_favorites_path(micropost_id: micropost.id), method: :delete %></p>
<div><%= hidden_field_tag :favorite_id, micropost.id %></div>
<% else %>
<p><span><%= micropost.favorites.count %></span>
<%= button_to 'お気に入り登録', micropost_favorites_path(micropost_id: micropost.id), method: :post %></p>
<div><%= hidden_field_tag :favorite_id, micropost.id %></div>
<% end %>
</div>
</li>
「 if !Favorite.exists?(user_id:current_user.id,post_id:post.id) 」
投稿に対してお気に入り登録しているか確認します。
<%= button_to 'お気に入り登録を削除', micropost_favorites_path(micropost_id: micropost.id), method: :delete %>
link_toでは上手く行かなかったのでbutton_toで実装しています。詳しくは下の記事を参考にしてください。
(Railsでlink_to deleteメソッドが動かない)
##コントローラの実装
class FavoritesController < ApplicationController
before_action :set_micropost
before_action :logged_in_user
def create
@favorite = Favorite.create(user_id: current_user.id, micropost_id: @micropost.id)
end
def destroy
@favorite = Favorite.find_by(user_id: current_user.id, micropost_id: @micropost.id)
@favorite.destroy
end
private
def set_micropost
@micropost = Micropost.find(params[:micropost_id])
end
end
set_micropostでリンクに含まれているparams[:micropost_id]を@micropostに代入。
その後にcreateアクション、destroyアクションが動きます。