From 924962023f7d50427a21b9a7a7eeaddaf9739e35 Mon Sep 17 00:00:00 2001 From: Daniel Dye Date: Fri, 11 Apr 2025 22:36:46 +0100 Subject: [PATCH 1/3] Add ability to pass block to association The return value of the block passed to the `association` call is automatically serialized. --- lib/transmutation/serializer.rb | 20 ++++++++++--------- spec/system/dummy/models/post.rb | 11 +++++----- .../api/v1/detailed/user_serializer.rb | 4 ++++ spec/system/rendering_spec.rb | 3 +++ 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/lib/transmutation/serializer.rb b/lib/transmutation/serializer.rb index 453f503..353c4c5 100644 --- a/lib/transmutation/serializer.rb +++ b/lib/transmutation/serializer.rb @@ -44,7 +44,7 @@ class << self # Define an attribute to be serialized # # @param attribute_name [Symbol] The name of the attribute to serialize - # @param block [Proc] The block to call to get the value of the attribute + # @yield [object] The block to call to get the value of the attribute # - The block is called in the context of the serializer instance # # @example @@ -66,21 +66,23 @@ def attribute(attribute_name, &block) # @param association_name [Symbol] The name of the association to serialize # @param namespace [String, Symbol, Module] The namespace to lookup the association's serializer in # @param serializer [String, Symbol, Class] The serializer to use for the association's serialization + # @yield [object] The block to call to get the value of the association + # - The block is called in the context of the serializer instance + # - The return value from the block is automatically serialized # # @example # class UserSerializer < Transmutation::Serializer # association :posts # association :comments, namespace: "Nested", serializer: "User::CommentSerializer" + # association :archived_posts do + # object.posts.archived + # end # end - def association(association_name, namespace: nil, serializer: nil) + def association(association_name, namespace: nil, serializer: nil, &custom_block) block = lambda do - serialize( - object.send(association_name), - namespace:, - serializer:, - depth: @depth + 1, - max_depth: @max_depth - ) + association_instance = custom_block ? instance_exec(&custom_block) : object.send(association_name) + + serialize(association_instance, namespace:, serializer:, depth: @depth + 1, max_depth: @max_depth) end attributes_config[association_name] = { block:, association: true } diff --git a/spec/system/dummy/models/post.rb b/spec/system/dummy/models/post.rb index a23d920..a5a0ac5 100644 --- a/spec/system/dummy/models/post.rb +++ b/spec/system/dummy/models/post.rb @@ -1,13 +1,14 @@ # frozen_string_literal: true class Post - attr_accessor :id, :title, :body, :user_id + attr_accessor :id, :title, :body, :user_id, :published_at - def initialize(id:, title:, body:, user_id: nil) + def initialize(id:, title:, body:, user_id: nil, published_at: nil) self.id = id self.title = title self.body = body self.user_id = user_id + self.published_at = published_at end def user @@ -20,9 +21,9 @@ def user def self.all [ - Post.new(id: 1, title: "First post", body: "First!", user_id: 1), - Post.new(id: 2, title: "How does this work?", body: "body", user_id: 2), - Post.new(id: 3, title: "Second post!?", body: "Nope...", user_id: 1) + Post.new(id: 1, title: "First post", body: "First!", user_id: 1, published_at: Time.now), + Post.new(id: 2, title: "How does this work?", body: "body", user_id: 2, published_at: Time.now), + Post.new(id: 3, title: "Second post!?", body: "Nope...", user_id: 1, published_at: nil) ] end diff --git a/spec/system/dummy/serializers/api/v1/detailed/user_serializer.rb b/spec/system/dummy/serializers/api/v1/detailed/user_serializer.rb index c7ae2b1..ab94c02 100644 --- a/spec/system/dummy/serializers/api/v1/detailed/user_serializer.rb +++ b/spec/system/dummy/serializers/api/v1/detailed/user_serializer.rb @@ -7,6 +7,10 @@ class UserSerializer < Api::V1::UserSerializer attributes :first_name, :last_name has_many :posts, namespace: "::Api::V1" + + has_many :published_posts, namespace: "::Api::V1" do + object.posts.reject { |post| post.published_at.nil? } + end end end end diff --git a/spec/system/rendering_spec.rb b/spec/system/rendering_spec.rb index 1a93e1a..828c88a 100644 --- a/spec/system/rendering_spec.rb +++ b/spec/system/rendering_spec.rb @@ -31,6 +31,9 @@ "posts" => [ { "id" => 1, "title" => "First post" }, { "id" => 3, "title" => "Second post!?" } + ], + "published_posts" => [ + { "id" => 1, "title" => "First post" } ] } end From 26b2578a0183db6fcbcc4f99c1538317801a9394 Mon Sep 17 00:00:00 2001 From: Daniel Dye Date: Fri, 11 Apr 2025 22:48:53 +0100 Subject: [PATCH 2/3] Add gem-release to development gems --- Gemfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Gemfile b/Gemfile index 9017091..c2c2d07 100644 --- a/Gemfile +++ b/Gemfile @@ -17,3 +17,5 @@ gem "simplecov-lcov" gem "undercover" gem "pry" + +gem "gem-release", require: false From 6abd99caf1feb7b4e697e5a3c73f1b9a7fdb79ea Mon Sep 17 00:00:00 2001 From: Daniel Dye Date: Fri, 11 Apr 2025 22:49:01 +0100 Subject: [PATCH 3/3] Bump transmutation to 0.5.0 --- lib/transmutation/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/transmutation/version.rb b/lib/transmutation/version.rb index 3fbf774..aac2780 100644 --- a/lib/transmutation/version.rb +++ b/lib/transmutation/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Transmutation - VERSION = "0.4.5" + VERSION = "0.5.0" end