ログインしているユーザーが記事に『いいね』できるAPIの実装 Rails

プログラミング
スポンサーリンク

ログインしているユーザーが記事に『いいね』できるAPIを実装

【使用したgem】

  • devise_token_auth
    ログイン情報をtokenで認証

  • active_model_selializer
    JSONオブジェクトを作成するオブジェクトの作成を支援するライブラリ。
    .

今回の場合、Railsのビューは使わない。

実装内容

User, Article, Likeの3つのモデルが必要。
.

User, Articleはすでに作ってあるので
.

Likeモデルの作成から始める。
.

LikeモデルはUser、Articleと1対多の関係なので
.

user:references article:references

.

このように記述して外部キーを作る
.

$ be rails g model Like user:references article:references

.

各modelにアソシエーションを記述。
.

class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  include DeviseTokenAuth::Concerns::User

  has_many :articles, dependent: :destroy
  has_many :comments, dependent: :destroy
  has_many :article_likes, dependent: :destroy
  has_many :comment_likes, dependent: :destroy
end


.

class Article < ApplicationRecord
  belongs_to :user
  has_many :comments, dependent: :destroy
  has_many :article_likes, dependent: :destroy

  validates :title, presence: true
  validates :content, presence: true
end

.

contentが空の場合エラーになるようにcommentモデルに記述。
.

validates :content, presence: true

.

いいねは
1つの記事につき、1つしかできないように設定するために以下を記述
.

validates :article_id, uniqueness: { scope: :user_id }

.

class ArticleLike < ApplicationRecord
  belongs_to :user
  belongs_to :article
  validates :article_id, uniqueness: { scope: :user_id }
end

.

これを書いておかないと
何個でもいいねが出来てしまう。

.

view側でいいねしている時としていない時を
.

if文で分岐できていれば大丈夫かもしれないが
.

今回はAPIの実装なので必要。
.

次にルーティングの設定をします。
.

記事にいいねをするので
.

ariticles配下に記述
.

Rails.application.routes.draw do
  namespace :v1 do
    mount_devise_token_auth_for "User", at: "auth", controllers: {
      registrations: "v1/auth/registrations",
    }

    resources :articles do
      resources :comments, controller: "articles/comments"
      resources :article_likes, controller: "articles/article_likes"
    end
  end
end

.

どの記事にいいねするのかURLでわかるように
ルーティングを変更する。

.

その他ルーティングの書き方に関してはこちらの記事を参考。
.

次にコントローラーを作成し
.

APIを実装していきます。
.

完成形がこちら。
.

class V1::Articles::ArticleLikesController < V1::BaseApiController
  def create
    current_user.article_likes.create!(article_id: params[:article_id])
    render json: { status: "ok" }
  end

  def destroy
    article = Article.find(params[:article_id])
    article_like = current_user.article_likes.find_by!(article: article)
    article_like.destroy!
    render json: { status: "ok" }
  end
end

.

create

def create
    current_user.article_likes.create!(article_id: params[:article_id])
    render json: { status: "ok" }
  end

.

こちらが完成系ですが

.

def create
    article = Article.find(params[:article_id])
    article_like = current_user.article_likes.new
    article_like.article = article
    article_like.save!
    render json: article_like
end

.

省略しなければこんな感じです。
.

いいねを作る時には
.

user_id,article_idが必要になる。
.

article = Article.find(params[:article_id])で記事を指定
.

current_user.article_likes.new
.

ログインしているユーザーのいいねを作成。
.

user_idが入る。

.

あと必要なのはarticle_idなので
.

article_like.article = articleで設定。

.

article_like.save!保存して
.

render json: commentJSONで返すように設定するのですが
.

「いいね」ボタンを押したときの反応が知りたいので、
article_likeの情報は特にいらない。
.

render json: { status: "ok" }

.

そうすると、処理に成功した場合は上記のようなレスポンスが返る。

destroy

def destroy
    article = Article.find(params[:article_id])
    article_like = current_user.article_likes.find_by!(article: article)
    article_like.destroy!
    render json: { status: "ok" }
  end

.

完成系がこちら。
.

いいねの削除機能は
ログインしているユーザーのいいねだけ削除できるようにする。
.

article_like = current_user.article_likes.find_by!(article: article)
.

ログインしているユーザーの記事といいねを指定。
.

article_like.destroy!削除して
render json: { status: "ok" }を返すようにして
.

完成。

関連記事

コメント

タイトルとURLをコピーしました