0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ブックマーク機能

Posted at

1. モデルの作成と関連付け

1.1 Bookmarkモデルの作成

bush

rails generate model Bookmark user:references tweet:references
rails db:migrate

1.2 モデル間の関連付けの設定

app/models/bookmark.rb

bookmark.rb
class Bookmark < ApplicationRecord
  belongs_to :user
  belongs_to :tweet
  
  # 同じユーザーが同じツイートを複数回ブックマークできないようにする
  validates :user_id, uniqueness: { scope: :tweet_id }
end

app/models/user.rb

user.rb
class User < ApplicationRecord
  # 既存の関連付けに追加
  has_many :bookmarks, dependent: :destroy
  has_many :bookmarked_tweets, through: :bookmarks, source: :tweet
end

app/models/tweets.rb

tweets.rb
class Tweet < ApplicationRecord
  # 既存の関連付けに追加
  has_many :bookmarks, dependent: :destroy
  has_many :bookmarked_by_users, through: :bookmarks, source: :user
end

2. ルーティングの設定

routes.rb
Rails.application.routes.draw do
  # 既存のルーティングに追加
  resources :tweets do
    member do
      post 'bookmark'
      delete 'unbookmark'
    end
  end
  
  # ブックマーク一覧用のルート
  get 'bookmarks', to: 'bookmarks#index'
end

3. コントローラーの実装

3.1 BookmarksControllerの作成

bush
rails generate controller Bookmarks index

app/controllersapp/controllers/bookmarks_controller.rb

bookmarks_controller.rb
class BookmarksController < ApplicationController
  before_action :authenticate_user!
  
  def index
    @bookmarked_tweets = current_user.bookmarked_tweets.includes(:user).order(created_at: :desc)
  end
end

3.2 TweetsControllerにブックマーク関連のアクションを追加

app/controllersapp/controllers/Tweets_controller.rb

tweets_controller.rb
class TweetsController < ApplicationController
  # 既存のアクションに追加
  
  def bookmark
    @tweet = Tweet.find(params[:id])
    current_user.bookmarks.create(tweet: @tweet)
    respond_to do |format|
      format.html { redirect_to @tweet }
      format.turbo_stream
    end
  end

  def unbookmark
    @tweet = Tweet.find(params[:id])
    current_user.bookmarks.find_by(tweet: @tweet).destroy
    respond_to do |format|
      format.html { redirect_to @tweet }
      format.turbo_stream
    end
  end
end

4. ビューの実装

4.1 ブックマークボタンのパーシャル作成

app/views/tweets/_bookmark_button.html.erb:

_bookmark_button.html.erb
<% if current_user&.bookmarked?(@tweet) %>
  <%= button_to tweet_unbookmark_path(@tweet), 
                method: :delete,
                class: "bookmark-button bookmarked",
                form: { data: { turbo: true } } do %>
    <i class="fas fa-bookmark"></i>
  <% end %>
<% else %>
  <%= button_to tweet_bookmark_path(@tweet),
                method: :post,
                class: "bookmark-button",
                form: { data: { turbo: true } } do %>
    <i class="far fa-bookmark"></i>
  <% end %>
<% end %>

4.2 ブックマーク一覧ページの作成

app/views/bookmarkers/index.html.erb:

index.html.erb
<div class="container">
  <h1>ブックマーク一覧</h1>
  
  <div class="tweets-list">
    <%= render partial: "tweets/tweet", collection: @bookmarked_tweets %>
  </div>
</div>

4.3 Turbo Streamテンプレートの作成

app/views/tweets/bookmark.turbo_stream.erb:

bookmark.turbo_stream.erb
<%= turbo_stream.replace "bookmark_button_#{@tweet.id}" do %>
  <%= render "tweets/bookmark_button", tweet: @tweet %>
<% end %>

app/views/tweets/unbookmark.turbo_stream.erb:

unbookmark.turbo_stream.erb
<%= turbo_stream.replace "bookmark_button_#{@tweet.id}" do %>
  <%= render "tweets/bookmark_button", tweet: @tweet %>
<% end %>

5. スタイルの追加(しなくてもいい)

scss
.bookmark-button {
  background: none;
  border: none;
  cursor: pointer;
  padding: 5px;
  
  i {
    font-size: 1.2rem;
    color: #657786;
  }
  
  &.bookmarked i {
    color: #1DA1F2;
  }
  
  &:hover i {
    color: #1DA1F2;
  }
}

6. ヘルパーメソッドの追加

app/helpers/tweets_helper.rb

tweets_helper.rb
module TweetsHelper
  def bookmarked?(tweet)
    current_user&.bookmarked_tweets&.include?(tweet)
  end
end

注意点
・ユーザー認証(Devise)が実装されていることを前提としている
・Font Awesomeなどのアイコンライブラリが必要
・Turbo/Hotwireが有効になっていることを確認
・必要に応じて適切なエラーハンドリングを追加
・この実装により、以下の機能が提供される:
ツイートのブックマーク追加/削除
ブックマーク一覧の表示
非同期でのブックマーク状態の更新
ユーザーごとのブックマーク管理

0
0
0

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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?