Skip to content

Commit

Permalink
Merge pull request #6 from MoskitoHero/context
Browse files Browse the repository at this point in the history
Add context argument to Serializer initializer
  • Loading branch information
MoskitoHero authored Jun 14, 2024
2 parents 5c0aa81 + 6fa2257 commit 12d27eb
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 7 deletions.
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,13 +224,14 @@ Of course, all the options available for the `one` and `many` macros are also av
```

## Context

You can pass a context to the serializer with the `with_context` method.

```ruby
serializer = PostSerializer.new(Post.last).with_context(current_user: current_user)
```

This context will be available in the serializer with the `context` method.
This context will be available in the serializer with the `context` method. It is also available in nested serializers.

```ruby
class PostSerializer < Barley::Serializer
Expand All @@ -239,9 +240,26 @@ class PostSerializer < Barley::Serializer
attribute :is_owner do
object.user == context.current_user
end

many :comments do
many :likes do
attribute :is_owner do
object.user == context.current_user # context is here too!
end
end
end
end
```

### Using a custom context object
Barley generates a Struct from the context hash you pass to the with_context method. But you can also pass a custom context object directly in the initializer instead.

```ruby
my_context = Struct.new(:current_user).new(current_user)

serializer = PostSerializer.new(Post.last, context: my_context)
```

## Generators
You have two generators available. One to generate the serializer class:

Expand Down
8 changes: 5 additions & 3 deletions lib/barley/serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def one(key, key_name: nil, serializer: nil, cache: false, &block)
return {} if element.nil?

el_serializer = serializer || element.serializer.class
el_serializer.new(element, cache: cache).serializable_hash
el_serializer.new(element, cache: cache, context: @context).serializable_hash
end
self.defined_attributes = (defined_attributes || []) << key_name
end
Expand Down Expand Up @@ -186,7 +186,7 @@ def many(key, key_name: nil, serializer: nil, cache: false, scope: nil, &block)
return [] if elements.empty?

el_serializer = serializer || elements.first.serializer.class
elements.map { |element| el_serializer.new(element, cache: cache).serializable_hash }.reject(&:blank?)
elements.map { |element| el_serializer.new(element, cache: cache, context: @context).serializable_hash }.reject(&:blank?)
end
self.defined_attributes = (defined_attributes || []) << key_name
end
Expand All @@ -201,8 +201,10 @@ def many(key, key_name: nil, serializer: nil, cache: false, scope: nil, &block)
# @param object [Object] the object to serialize
# @param cache [Boolean, Hash<Symbol, ActiveSupport::Duration>] a boolean to cache the result, or a hash with options for the cache
# @param root [Boolean] whether to include the root key in the hash
def initialize(object, cache: false, root: false)
# @param context [Object] an optional context object to pass additional data to the serializer
def initialize(object, cache: false, root: false, context: nil)
@object = object
@context = context
@root = root
@cache, @expires_in = if cache.is_a?(Hash)
[true, cache[:expires_in]]
Expand Down
4 changes: 2 additions & 2 deletions sig/barley/serializer.rbs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Barley
class Serializer
@cache: bool
@context: Struct[untyped]
@context: untyped
@expires_in: ActiveSupport::Duration
@root: bool

Expand All @@ -13,7 +13,7 @@ class Serializer
def self.one: (Symbol key, ?key_name: Symbol, ?serializer: Serializer, ?cache: bool | Hash[Symbol, ActiveSupport::Duration]) ?{ () -> void } -> (Hash[untyped, untyped] | [untyped])
def self.many: (Symbol key, ?key_name: Symbol, ?serializer: Serializer, ?cache: bool | Hash[Symbol, ActiveSupport::Duration], ?scope: ^() -> void ) ?{ () -> void } -> Array[untyped]
def self.set_class_iv: (Symbol iv, Symbol key) -> [untyped]
def initialize: (untyped object, ?cache: bool | Hash[Symbol, ActiveSupport::Duration], ?root: bool) -> void
def initialize: (untyped object, ?cache: bool | Hash[Symbol, ActiveSupport::Duration], ?root: bool, ?context: untyped) -> void
def serializable_hash: -> Hash[Symbol, untyped]
def clear_cache: (?key: String) -> untyped
def with_context:(*(Hash[Symbol, untyped])) -> self
Expand Down
19 changes: 18 additions & 1 deletion test/barley/serializer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ class SerializerTest < ActiveSupport::TestCase
attributes :id, :email

attribute :note do
context[:note]
context.note
end
end
expected = {
Expand All @@ -137,6 +137,23 @@ class SerializerTest < ActiveSupport::TestCase
assert_equal(expected, serializer.new(@user).with_context(note: "new note").serializable_hash)
end

test "it serializes with a context object given to the initializer" do
my_context = Struct.new(:note).new("new note")
serializer = Class.new(Barley::Serializer) do
attributes :id, :email

attribute :note do
context.note
end
end
expected = {
id: @user.id,
email: @user.email,
note: "new note"
}
assert_equal(expected, serializer.new(@user, context: my_context).serializable_hash)
end

test "it serializes a many association with a named scope" do
serializer = Class.new(Barley::Serializer) do
attributes :id, :email
Expand Down

0 comments on commit 12d27eb

Please sign in to comment.