Search code examples
ruby-on-railsactive-model-serializers

Active Model Serializers nested associations that calls methods with arguments


for example if I have these models with these associations

class User 
  has_many :posts
  has_many :comments

  def posts_has_comments_in_certain_day(day)
    posts.joins(:comments).where(comments: { created_at: day })
  end 
end

class Post
  has_many :comments
  belongs_to :user

  def comments_in_certain_day(day)
    Comment.where(created_at: day, post_id: id)
  end
end

class Comment
  belongs_to :user
  belongs_to :post
end

now I want active model serializer to get me all the users with their posts that has comments in a certain day including these comments too.

I've tried but all I could get is user with his posts that have comments in that certain day .. but I couldn't include the comments too.

thats what I did

class UserSerializer < ActiveModel::Serializer
  attributes :id, :name, :day_posts

  def day_posts
    object.posts_has_comments_in_certain_day(day)
  end
end

and this is working fine but when I try to include the comments !!! ..

class UserSerializer < ActiveModel::Serializer
  attributes :id, :name, :day_posts

  def day_posts
    object.posts_has_comments_in_certain_day(day).map do |post|
    PostSerializer.new(
      post,
      day: instance_options[:day]
    )
  end
end

class PostSerializer < ActiveModel::Serializer
  attributes :id, :body, :day_comments

  def day_comments
    object.comments_in_certain_day(day)
  end
end

this is not working .. can any one help me with this ?


Solution

  • Call .attributes on serializer instance

    class UserSerializer < ActiveModel::Serializer
      attributes :id, :name, :day_posts
    
      def day_posts
        object.posts_has_comments_in_certain_day(day).map do |post|
        PostSerializer.new(
          post,
          day: instance_options[:day]
        ).attributes
      end
    end
    

    if you need to customise comments attributes do the same thing for comments too.

    class PostSerializer < ActiveModel::Serializer
      attributes :id, :body, :day_comments
    
      def day_comments
        object.comments_in_certain_day(day).map do |comment|
            CommentSerializer.new(comment).attributes
        end
      end
    end