rails로 동영상 사이트에 좋아 기능 구현
동영상 사이트에 좋은 기능을 구현해 보았습니다.
지금은 당연하게 되고 있는 좋은 기능이지만, 어떻게 만들어지고 있는지 궁금해 포트폴리오에 시험에 실장해 보았습니다. 1 유저가 복수의 동영상에 대해서 좋아하고, 또 1 동영상에 대해 복수의 유저가 좋아하는, 이른바 다대다의 관계이므로, 유저와 동영상의 중간 테이블로서 좋아요 테이블을 작성해 갑니다.
 완성도
 
 환경
rails : v5.2.4.1
~ 구현된 기능 ~
・동영상(일람 표시, 신규 투고, 상세, 편집, 삭제)
· 사용자(신규 등록, 로그인, 편집, 로그아웃, 상세)
· 페이지 네이션
 구현 절차
※좋아 기능에 관한 부분만 코멘트 아웃으로 설명 쓰고 있습니다.
$ rails g model Like user:references video:references
$ rails db:migrate
models/user.rb
class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  validates :name, presence: true, uniqueness: true
  has_many :videos, dependent: :destroy
  # いいねはユーザーのdestroyに依存
  has_many :likes, dependent: :destroy
  # ユーザーがいいねしている動画
  has_many :liked_videos, through: :likes, source: :video
  # いいねしているかどうかを判定
  def already_liked?(video)
    self.likes.exists?(video_id: video.id)
  end
end
models/video.rb
class Video < ApplicationRecord
  validates :name, :work, presence: true
  belongs_to :user
  # いいねは動画のdestroyに依存
  has_many :likes, dependent: :destroy
  # 動画にいいねしているユーザー
  has_many :liked_users, through: :likes, source: :user
  mount_uploader :work, VideoUploader
end
models/like.rb
class Like < ApplicationRecord
  belongs_to :user
  belongs_to :video
  # 1人が1つの動画に1いいね
  validates_uniqueness_of :video_id, scope: :user_id
end
$ rails g controller likes
config/routes.rb
Rails.application.routes.draw do
  devise_for :users
  root "videos#index"
  resources :users, only: [:edit, :update, :show]
  # いいねを動画にネストさせる
  resources :videos do
    resources :likes, only: [:create, :destroy]
  end
end
controllers/likes_controller.rb
class LikesController < ApplicationController
  def create
    # 今ログインしているユーザーによるいいね
    @like = current_user.likes.create(video_id: params[:video_id])
    # 今いる画面にリダイレクト
    redirect_back(fallback_location: root_path)
  end
  def destroy
    # 今ログインしているユーザーがいいねしている動画を探す
    @like = Like.find_by(video_id: params[:video_id], user_id: current_user.id)
    # いいねを取り消す
    @like.destroy
    # 今いる画面にリダイレクト
    redirect_back(fallback_location: root_path)
  end
end
controllers/videos_controller.rb
class VideosController < ApplicationController
  def index
    @videos = Video.includes(:user).page(params[:page]).order("created_at DESC").per(12)
  end
  def new
    @video = Video.new
  end
  def create
    Video.create(video_params)
    redirect_to root_path
  end
  def show
    @video = Video.find(params[:id])
    # いいねする
    @like = Like.new
  end
  def edit
    @video = Video.find(params[:id])
  end
  def update
    video = Video.find(params[:id])
    video.update(video_params)
  end
  def destroy
    video = Video.find(params[:id])
    video.destroy
    redirect_to root_path
  end
  private
  def video_params
    params.require(:video).permit(:name, :work).merge(user_id: current_user.id)
  end
end
end
로그인하지 않은 사용자도 좋아요 수를 볼 수 있도록하려면 분기 필요
show.html.haml
-# ログインしている場合
- if user_signed_in?
  -# かつ既にいいねしている場合
  - if current_user.already_liked?(@video)
    = link_to video_like_path(@video), method: :delete do
      = icon('fa', 'heart', class: 'content__show__box__top__icons__heart__already')
  -# かつまだいいねしていない場合
  - else
    = link_to video_likes_path(@video), method: :post do
      = icon('far', 'heart', class: 'content__show__box__top__icons__heart__yet')
-# ログインしていない場合
- else
  = icon('far', 'heart', class: 'content__show__box__top__icons__heart__yet')
    = @video.likes.count
video의 index 컨트롤러에서는 video의 id 컬럼을 취득할 수 없고, 에러로 nil이 돌려주어져 버린다.
그 때문에 일람 화면에서는 표시만으로 해, 좋아 버튼은 동작하지 않게 설정.
index.html.haml
-# ログインしている場合、かつ既にいいねしている場合
- if user_signed_in? && current_user.already_liked?(video)
  = icon('fa', 'heart', class: 'content__box__top__icons__heart__already')
-# それ意外の場合
- else
  = icon('far', 'heart', class: 'content__box__top__icons__heart__yet')
    = video.likes.count
도전
참고
Reference
이 문제에 관하여(rails로 동영상 사이트에 좋아 기능 구현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/naoki00m/items/9d90e919a02b34f6132d텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)