docbrown/app/serializers/homepage/article_serializer.rb
Jeremy Friesen c5bf4bf880
Extracting duplicate logic (#16035)
Prior to this commit, we had two places that need to know the nuances
ofquerying for tag flares and what we should include in our queries for
serialization.

With this commit, we're factoring towards a common source of knowledge
and providing a much needed test for the expected output of this
serialization.

Loosely related to #15916, #15983, #15994, and #16032.
2022-01-10 15:19:04 -05:00

58 lines
1.8 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,
:comments_count,
:id,
:path,
:public_reactions_count,
:readable_publish_date,
:reading_time,
:title,
:user_id,
)
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