0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

お気に入り機能を実装する

Last updated at Posted at 2021-01-25

#はじめに
エンジニア転職のためポートフォリオを作成しているkazuです。
Railチュートリアルで作った制作物にいいね機能を実装しました!

Railsチュートリアルを一通り終えた方が読者の対象です。
#実装順序
1.ルーティング
2.モデルの設定
3.いいねの表示
4.コントローラの実装
##ルーティング

config/routes.rb
  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 といったメソッドチェーンが使えるようになります。
 

***_create_favorite.rb
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

マイグレーションファイルをデータベースに反映します。

favorite.rb
class Favorite < ApplicationRecord
  belongs_to :user
  belongs_to :micropost

  validates :user_id, presence: true
  validates :micropost_id, presence: true
end

モデルのファイルは、こんな感じに。
##いいねボタンの表示

app/views/home.html.erb
<% 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の要素に対して、パーシャルが呼び出されます。

app/views/microposts/_microposts.html.erb
<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 %>

<%= hidden_field_tag :favorite_id, micropost.id %>
お気に入り登録を削除するリンクです。
link_toでは上手く行かなかったのでbutton_toで実装しています。詳しくは下の記事を参考にしてください。
(Railsでlink_to deleteメソッドが動かない)

##コントローラの実装

app/controllers/favorites_controller.rb
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アクションが動きます。

0
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?