Skip to content

Commit 0f01b17

Browse files
authored
Refactor Category to use dedicated dist serializers (#563)
### TL;DR Follow up to #531: moves category serialization logic into dedicated serializer classes for JSON and TXT formats. ### What changed? - Created new `JsonSerializer` and `TxtSerializer` classes for category serialization - Moved JSON serialization methods from `Category` model to `JsonSerializer` - Moved TXT serialization methods from `Category` model to `TxtSerializer` - Updated `GenerateDistCommand` to use the new serializer classes - Added corresponding test files for both serializers
2 parents a42be34 + 3c5dcd4 commit 0f01b17

File tree

8 files changed

+462
-310
lines changed

8 files changed

+462
-310
lines changed

dev/lib/product_taxonomy.rb

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ def data_path = DATA_PATH
3030
require_relative "product_taxonomy/models/serializers/category/data/localizations_serializer"
3131
require_relative "product_taxonomy/models/serializers/category/docs/siblings_serializer"
3232
require_relative "product_taxonomy/models/serializers/category/docs/search_serializer"
33+
require_relative "product_taxonomy/models/serializers/category/dist/json_serializer"
34+
require_relative "product_taxonomy/models/serializers/category/dist/txt_serializer"
3335
require_relative "product_taxonomy/models/serializers/attribute/data/localizations_serializer"
3436
require_relative "product_taxonomy/models/serializers/attribute/docs/base_and_extended_serializer"
3537
require_relative "product_taxonomy/models/serializers/attribute/docs/reversed_serializer"

dev/lib/product_taxonomy/commands/generate_dist_command.rb

+5-2
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ def generate_dist_files(locale)
5050

5151
def generate_txt_file(locale:, type:)
5252
txt_data = case type
53-
when "categories" then Category.to_txt(version: @version, locale:)
5453
when "attributes" then Serializers::Attribute::Dist::TxtSerializer.serialize_all(version: @version, locale:)
54+
when "categories" then Serializers::Category::Dist::TxtSerializer.serialize_all(version: @version, locale:)
5555
when "taxonomy" then return
5656
when "attribute_values" then Serializers::Value::Dist::TxtSerializer.serialize_all(version: @version, locale:)
5757
end
@@ -62,7 +62,10 @@ def generate_txt_file(locale:, type:)
6262
def generate_json_file(locale:, type:)
6363
json_data = case type
6464
when "categories"
65-
@categories_json_by_locale[locale] ||= Category.to_json(version: @version, locale:)
65+
@categories_json_by_locale[locale] ||= Serializers::Category::Dist::JsonSerializer.serialize_all(
66+
version: @version,
67+
locale:,
68+
)
6669
when "attributes"
6770
@attributes_json_by_locale[locale] ||= Serializers::Attribute::Dist::JsonSerializer.serialize_all(
6871
version: @version,

dev/lib/product_taxonomy/models/category.rb

-78
Original file line numberDiff line numberDiff line change
@@ -42,41 +42,6 @@ def load_from_source(source_data)
4242
@verticals.sort_by!(&:name)
4343
end
4444

45-
# Get the JSON representation of all verticals.
46-
#
47-
# @param version [String] The version of the taxonomy.
48-
# @param locale [String] The locale to use for localized attributes.
49-
# @return [Hash] The JSON representation of all verticals.
50-
def to_json(version:, locale: "en")
51-
{
52-
"version" => version,
53-
"verticals" => verticals.map do
54-
{
55-
"name" => _1.name(locale:),
56-
"prefix" => _1.id,
57-
"categories" => _1.descendants_and_self.map { |category| category.to_json(locale:) },
58-
}
59-
end,
60-
}
61-
end
62-
63-
# Get the TXT representation of all verticals.
64-
#
65-
# @param version [String] The version of the taxonomy.
66-
# @param locale [String] The locale to use for localized attributes.
67-
# @param padding [Integer] The padding to use for the GID. Defaults to the length of the longest GID.
68-
# @return [String] The TXT representation of all verticals.
69-
def to_txt(version:, locale: "en", padding: longest_gid_length)
70-
header = <<~HEADER
71-
# Shopify Product Taxonomy - Categories: #{version}
72-
# Format: {GID} : {Ancestor name} > ... > {Category name}
73-
HEADER
74-
[
75-
header,
76-
*all_depth_first.map { _1.to_txt(padding:, locale:) },
77-
].join("\n")
78-
end
79-
8045
# Reset all class-level state
8146
def reset
8247
@localizations = nil
@@ -103,10 +68,6 @@ def add_children(type:, item:, parent:)
10368
end
10469
end
10570
end
106-
107-
def longest_gid_length
108-
all.max_by { _1.gid.length }.gid.length
109-
end
11071
end
11172

11273
validates :id, format: { with: /\A[a-z]{2}(-\d+)*\z/ }
@@ -266,45 +227,6 @@ def friendly_name
266227
"#{id}_#{IdentifierFormatter.format_friendly_id(name)}"
267228
end
268229

269-
#
270-
# Serialization
271-
#
272-
273-
def to_json(locale: "en")
274-
{
275-
"id" => gid,
276-
"level" => level,
277-
"name" => name(locale:),
278-
"full_name" => full_name(locale:),
279-
"parent_id" => parent&.gid,
280-
"attributes" => attributes.map do
281-
{
282-
"id" => _1.gid,
283-
"name" => _1.name(locale:),
284-
"handle" => _1.handle,
285-
"description" => _1.description(locale:),
286-
"extended" => _1.is_a?(ExtendedAttribute),
287-
}
288-
end,
289-
"children" => children.map do
290-
{
291-
"id" => _1.gid,
292-
"name" => _1.name(locale:),
293-
}
294-
end,
295-
"ancestors" => ancestors.map do
296-
{
297-
"id" => _1.gid,
298-
"name" => _1.name(locale:),
299-
}
300-
end,
301-
}
302-
end
303-
304-
def to_txt(padding: 0, locale: "en")
305-
"#{gid.ljust(padding)} : #{full_name(locale:)}"
306-
end
307-
308230
private
309231

310232
#
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# frozen_string_literal: true
2+
3+
module ProductTaxonomy
4+
module Serializers
5+
module Category
6+
module Dist
7+
module JsonSerializer
8+
class << self
9+
def serialize_all(version:, locale: "en")
10+
{
11+
"version" => version,
12+
"verticals" => ProductTaxonomy::Category.verticals.map do |vertical|
13+
{
14+
"name" => vertical.name(locale:),
15+
"prefix" => vertical.id,
16+
"categories" => vertical.descendants_and_self.map { |category| serialize(category, locale:) },
17+
}
18+
end,
19+
}
20+
end
21+
22+
# @param category [Category]
23+
# @param locale [String] The locale to use for localization.
24+
# @return [Hash]
25+
def serialize(category, locale: "en")
26+
{
27+
"id" => category.gid,
28+
"level" => category.level,
29+
"name" => category.name(locale:),
30+
"full_name" => category.full_name(locale:),
31+
"parent_id" => category.parent&.gid,
32+
"attributes" => category.attributes.map do |attr|
33+
{
34+
"id" => attr.gid,
35+
"name" => attr.name(locale:),
36+
"handle" => attr.handle,
37+
"description" => attr.description(locale:),
38+
"extended" => attr.is_a?(ExtendedAttribute),
39+
}
40+
end,
41+
"children" => category.children.map do |child|
42+
{
43+
"id" => child.gid,
44+
"name" => child.name(locale:),
45+
}
46+
end,
47+
"ancestors" => category.ancestors.map do |ancestor|
48+
{
49+
"id" => ancestor.gid,
50+
"name" => ancestor.name(locale:),
51+
}
52+
end,
53+
}
54+
end
55+
end
56+
end
57+
end
58+
end
59+
end
60+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# frozen_string_literal: true
2+
3+
module ProductTaxonomy
4+
module Serializers
5+
module Category
6+
module Dist
7+
module TxtSerializer
8+
class << self
9+
def serialize_all(version:, locale: "en", padding: longest_gid_length)
10+
header = <<~HEADER
11+
# Shopify Product Taxonomy - Categories: #{version}
12+
# Format: {GID} : {Ancestor name} > ... > {Category name}
13+
14+
HEADER
15+
16+
categories_txt = ProductTaxonomy::Category
17+
.all_depth_first
18+
.map { |category| serialize(category, padding:, locale:) }
19+
.join("\n")
20+
21+
header + categories_txt
22+
end
23+
24+
# @param category [Category]
25+
# @param padding [Integer] The padding to use for the GID.
26+
# @param locale [String] The locale to use for localization.
27+
# @return [String]
28+
def serialize(category, padding:, locale: "en")
29+
"#{category.gid.ljust(padding)} : #{category.full_name(locale:)}"
30+
end
31+
32+
private
33+
34+
def longest_gid_length
35+
ProductTaxonomy::Category.all.max_by { |c| c.gid.length }.gid.length
36+
end
37+
end
38+
end
39+
end
40+
end
41+
end
42+
end

0 commit comments

Comments
 (0)