Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide default alias/naming option at Representer-level #131

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,20 @@ end
song.to_json #=> {"name":"Fallout","track":1}
```

You can also a naming strategy at a Representer-level:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing a verb here ;-)

I guess it should read

You can also provide a naming strategy at a Representer-level:


```ruby
module SongRepresenter
include Representable::JSON

self.naming_strategy = ->(name) { name.camelize } # (with ActiveSupport available)

property :song_title
property :song_track, as: :track
end

song.to_json #=> {"songTitle":"Fallout","track":1}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you were using the camelize of ActiveSupport (as indicated), it would read SongTitle and Track.

Either use camelize(:lower) as example code above or change the JSON here to upper camel case.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NobodysNightmare quite right!

```

## Wrapping

Expand Down
13 changes: 12 additions & 1 deletion lib/representable/declarative.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
module Representable
module Declarative
def naming_strategy=(strategy)
raise 'The :naming_strategy option should respond to #call?' \
unless strategy.respond_to?(:call)

@naming_strategy = strategy
end

def representable_attrs
@representable_attrs ||= build_config
end
Expand Down Expand Up @@ -33,6 +40,8 @@ def nested(name, options={}, &block)
end

def property(name, options={}, &block)
options = { as: naming_strategy.(name.to_s) }.merge(options) if naming_strategy

representable_attrs.add(name, options) do |default_options| # handles :inherit.
build_definition(name, default_options, &block)
end
Expand All @@ -49,6 +58,8 @@ def build_inline(base, features, name, options, &block) # DISCUSS: separate modu
end

private
attr_reader :naming_strategy

# This method is meant to be overridden if you want to add or change DSL options.
# The options hash is already initialized, add or change elements as you need.
#
Expand Down Expand Up @@ -83,4 +94,4 @@ def build_config
Config.new
end
end # Declarations
end
end
64 changes: 64 additions & 0 deletions test/as_strategy_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
require 'test_helper'

class AsStrategyTest < BaseTest
let(:format) { :hash }
let(:song) { representer.prepare(Struct.new(:title).new('Revolution')) }

class ReverseNamingStrategy
def call(name)
name.reverse
end
end

describe 'module' do
describe 'with lambda' do
let(:output) { { 'TITLE' => 'Revolution' } }
let(:input) { { 'TITLE' => 'Wie es geht' } }

representer! do
self.naming_strategy = ->(name) { name.upcase }
property :title
end

it { render(song).must_equal_document(output) }
it { parse(song, input).title.must_equal('Wie es geht') }
end

describe 'with class responding to #call?' do
let(:output) { { 'eltit' => 'Revolution' } }
let(:input) { { 'eltit' => 'Wie es geht' } }

representer! do
self.naming_strategy = ReverseNamingStrategy.new
property :title
end

it { render(song).must_equal_document(output) }
it { parse(song, input).title.must_equal('Wie es geht') }
end

describe 'with class not responding to #call?' do
representer! do
self.naming_strategy = Object.new
property :title
end

it { -> { render(song) }.must_raise(RuntimeError) }
end
end

describe 'decorator' do
describe 'with a lambda' do
let(:output) { { 'TITLE' => 'Revolution' } }
let(:input) { { 'TITLE' => 'Wie es geht' } }

representer!(decorator: true) do
self.naming_strategy = ->(name) { name.upcase }
property :title
end

it { render(song).must_equal_document(output) }
it { parse(song, input).title.must_equal('Wie es geht') }
end
end
end
12 changes: 11 additions & 1 deletion test/as_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ class AsTest < MiniTest::Spec
it { parse(song, input).name.must_equal "Wie Es Geht" }
end

describe "as: with :symbol, overriding naming_strategy default" do
representer!(module: mod) do
self.naming_strategy = ->(name) { name.upcase }

property :name, as: :title
end

it { render(song).must_equal_document output }
it { parse(song, input).name.must_equal 'Wie Es Geht' }
end

describe "as: with lambda" do
representer!(:module => mod) do
Expand All @@ -40,4 +50,4 @@ class AsTest < MiniTest::Spec
it { parse(song, {"[{:volume=>1}]" => "Wie Es Geht"}, :volume => 1).name.must_equal "Wie Es Geht" }
end
end
end
end