Skip to content

Commit

Permalink
Add CacheCrispies::Base#transform_keys method
Browse files Browse the repository at this point in the history
  • Loading branch information
wujibear committed Dec 18, 2022
1 parent dea85f8 commit 74eb163
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 3 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,28 @@ end

Put serializer files in `app/serializers/`. For instance this file should be at `app/serializers/cereal_serializer.rb`.

### Snakecase to lower camel case
You can pass a method to `transform_keys` in a serializer which will transform the keys for each attribute unless a `from` attribute was specified for that attribute.
The configuration for `transform_keys` can be inherited, and overridden in the serializers that inherit from another.
```ruby
# app/serializers/base_serializer.rb
class BaseSerializer < CacheCrispies::Base
transform_keys lambda { |key| key.to_s.camelize(:lower) }
end

# app/serializers/crispy_serializer.rb
class CrispySerializer < BaseSerializer
serialize :id, :created_at
end
```
This will format the keys for each attribute using the passed in lambda like so:
```json
{
"id": "123",
"createdAt": "somedate"
}
```

### In your Rails controller
```ruby
class CerealsController
Expand Down
25 changes: 23 additions & 2 deletions lib/cache_crispies/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,16 @@ def self.file_hashes
).uniq.sort
end

# Sets a method or Proc to transform keys by
#
# @param proc [Proc] a Proc to execute on serializable keys
# @return [Proc] a Proc to execute on the keys
def self.transform_keys(proc = nil)
return @transform_keys ||= proc if proc.present? || @transform_keys.present?

self.superclass.transform_keys if self.superclass.respond_to?(:transform_keys)
end

private

def self.file_hash
Expand Down Expand Up @@ -226,13 +236,14 @@ def self.serialize(
)
attribute_names.flat_map do |attrib|
attrib = attrib&.to_sym
key = attrib
current_nesting = Array(@nesting).dup
current_conditions = Array(@conditions).dup

@attributes <<
Attribute.new(
attrib,
from: from,
transform_key(attrib),
from: from || attrib,
with: with,
through: through,
to: to,
Expand All @@ -250,5 +261,15 @@ def self.merge(attribute = nil, with: nil)
serialize(nil, from: attribute, with: with)
end
private_class_method :merge

# Transforms an attribute key using a specified Proc
#
# @param key [String] the key for an attribute
# @return [String] a transformed key
def self.transform_key(key)
return key if transform_keys.blank?

transform_keys.call(key)
end
end
end
33 changes: 32 additions & 1 deletion spec/cache_crispies/base_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ def visible?
end
end

class BaseSerializer < CacheCrispies::Base
transform_keys lambda { |key| key.to_s.camelize(:lower) }
end

class InheritingSerializer < BaseSerializer
serialize :id, :snake_case
end

class OverriddenSerializer < BaseSerializer
transform_keys lambda { |key| key.to_s.upcase }

serialize :id, :snake_case
end

let(:model) do
OpenStruct.new(
id: 42,
Expand All @@ -47,7 +61,8 @@ def visible?
deeply_nested: true,
nutrition_info: OpenStruct.new(calories: 1_000),
organic: 'true',
legal: OpenStruct.new(parent_company: 'Disney probably')
legal: OpenStruct.new(parent_company: 'Disney probably'),
snake_case: 'i was snakecased'
)
end

Expand Down Expand Up @@ -95,6 +110,22 @@ def visible?
end
end

describe '.transform_keys' do
let(:serializer) { InheritingSerializer }

it 'transforms attribute keys' do
expect(subject.as_json.keys).to eq(%w[id snakeCase])
end

describe 'overridden serializers' do
let(:serializer) { OverriddenSerializer }

it 'transforms attribute keys' do
expect(subject.as_json.keys).to eq(%w[ID SNAKE_CASE])
end
end
end

describe '.key' do
it 'underscores the demodulized class name by default' do
expect(serializer.key).to eq :cache_crispies_test
Expand Down

0 comments on commit 74eb163

Please sign in to comment.