RailsでSerializerを使ってログインしたUserがLikeできるItem列をPaginationしたい

詰まった点

Serializer側で、「ユーザはログインしているか」と「ユーザは過去にLikeしたか」を判断して値を返さなければいけないがActiveModel::Serializer::CollectionSerializerを使ってどうやってやる?

解決策

ActiveModel::Serializer::CollectionSerializerの#initialize(resources, options = {}) のoptions[:item_likes]にログインしてないならfalseをわたし、ログインしているならそのユーザのitem_likesをわたす

モデルはこんな感じ

  • User
    • has_many: item_likes
  • Item
    • has_many: item_likes
  • ItemLike
    • belongs_to: user
    • belongs_to: item

コントローラはこんな感じ

    items_json = ActiveModel::Serializer::CollectionSerializer.new(
      Item.hogehoge.page(@page),
      serializer: ItemSerializer,
      item_likes: user_signed_in? && current_user.item_likes
    ).as_json

    render json: {
      items: items_json,
      length: length
    }, status: :ok

Serializerはこんな感じ

class ItemSerializer < ActiveModel::Serializer
  attributes %i[id is_liked]

  def initialize(object, options = {})
    super
    @item_likes = options[:item_likes]
  end

  def is_liked
    @item_likes && @item_likes.exists?(item_id: object[:id])
  end
end

参考

www.rubydoc.info

qiita.com