docbrown/app/serializers/homepage/article_serializer.rb
Anna Buianova 51316c747f
Comments count according to display rules in feed (#20753)
* Move calculating comments score from worker to a service

* Display displayed comments count in feed

* Recalculating displayed comments counts on article show (if needed)

* Rubocop fixes

* Fixed lambda
2024-03-28 12:12:05 +00:00

62 lines
2 KiB
Ruby

module Homepage
class ArticleSerializer < ApplicationSerializer
# @param relation [ActiveRecord::Relation<Article>]
#
# @return [Hash]
def self.serialized_collection_from(relation:)
# Unfortunately the FlareTag class sends one SQL query per each article,
# as we want to optimize by loading them in one query, we're using a different class
tag_flares = Homepage::FetchTagFlares.call(relation)
# including user and organization as the last step as they are not needed
# by the query that fetches tag flares, they are only needed by the serializer
relation = relation.includes(:user, :organization)
new(relation, params: { tag_flares: tag_flares }, is_collection: true)
.serializable_hash[:data]
.pluck(:attributes)
end
attributes(
:class_name,
:cloudinary_video_url,
:id,
:path,
:public_reactions_count,
:readable_publish_date,
:reading_time,
:title,
:user_id,
:public_reaction_categories,
)
# return displayed_comments_count (excluding low score comments) if it was calculated earlier
attribute :comments_count, (lambda do |article|
article.displayed_comments_count? ? article.displayed_comments_count : article.comments_count
end)
attribute :video_duration_string, &:video_duration_in_minutes
attribute :published_at_int, ->(article) { article.published_at.to_i }
attribute :tag_list, ->(article) { article.cached_tag_list.to_s.split(", ") }
attribute :flare_tag, ->(article, params) { params.dig(:tag_flares, article.id) }
attribute :user do |article|
user = article.user
{
name: user.name,
profile_image_90: user.profile_image_90,
username: user.username
}
end
attribute :organization, if: proc { |a| a.organization.present? } do |article|
organization = article.organization
{
name: organization.name,
profile_image_90: article.organization.profile_image_90,
slug: organization.slug
}
end
end
end