1. 前提
- ログイン機能と投稿機能は既にある
- 投稿一覧・詳細は表示できる状態
ここから「ブックマーク機能」を追加し、users/show.html.erb に保存済み投稿を一覧表示します。
2. モデル作成
コマンドプロンプト
rails g model Bookmark user:references post:references
rails db:migrate
3. モデルの関連付け
app/models/bookmark.rb
class Bookmark < ApplicationRecord
belongs_to :user
belongs_to :post
validates :user_id, uniqueness: { scope: :post_id }
end
app/models/user.rb
class User < ApplicationRecord
has_many :bookmarks, dependent: :destroy
has_many :bookmarked_posts, through: :bookmarks, source: :post
def bookmarked?(post)
bookmarks.exists?(post_id: post.id)
end
end
```ruby:app/models/post.rb
class Post < ApplicationRecord
has_many :bookmarks, dependent: :destroy
end
4. ルーティングを追加
config/routes.rb
resources :posts do
resource :bookmark, only: [:create, :destroy]
end
5. BookmarksController作成
rails g controller Bookmarks
```ruby:app/controllers/bookmarks_controller.rb
class BookmarksController < ApplicationController
before_action :authenticate_user!
before_action :set_post
def create
current_user.bookmarks.find_or_create_by!(post: @post)
redirect_back fallback_location: @post, notice: '保存しました'
end
def destroy
current_user.bookmarks.where(post: @post).destroy_all
redirect_back fallback_location: @post, notice: '保存を解除しました'
end
private
def set_post
@post = Post.find(params[:post_id])
end
end
6. 投稿ページにブックマークボタンを追加
一覧ページ(index)
app/views/posts/index.html.erb
<% if user_signed_in? %>
<% if current_user.bookmarked?(t) %>
<%= button_to '保存を解除', post_bookmark_path(t), method: :delete %>
<% else %>
<%= button_to '保存する', post_bookmark_path(t), method: :post %>
<% end %>
<% end %>
投稿詳細(show)
app/views/posts/show.html.erb
<% if user_signed_in? %>
<% if current_user.bookmarked?(@post) %>
<%= button_to '保存を解除', post_bookmark_path(@post), method: :delete %>
<% else %>
<%= button_to '保存する', post_bookmark_path(@post), method: :post %>
<% end %>
<% end %>
7. ユーザーマイページで保存済み投稿を表示
app/controllers/users_controller.rb
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
@bookmarked_posts = @user.bookmarked_posts # 追加
end
end
users/show.html.erb
<h2>保存済みの投稿</h2>
<% if @bookmarked_posts.any? %>
<ul>
<% @bookmarked_posts.each do |post| %>
<li>
<%= link_to post.body, post_path(post) %>
</li>
<% end %>
</ul>
<% else %>
<p>保存済みの投稿はありません。</p>
<% end %>