Skip to content

Commit

Permalink
Add alternate string identifier support for Resource.find
Browse files Browse the repository at this point in the history
This allows the usage of non-Fixnum unique identifiers for GETs for a
specific resource as long as a matching _link is defined in the Api
Schema.
  • Loading branch information
Derek Lindahl committed Apr 6, 2015
1 parent 4b33d12 commit 480ea5a
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/frenetic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

require 'frenetic/version'
require 'frenetic/errors'
require 'frenetic/behaviors'
require 'frenetic/briefly_memoizable'
require 'frenetic/connection'
require 'frenetic/middleware/hal_json'
Expand Down
6 changes: 6 additions & 0 deletions lib/frenetic/behaviors.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require 'frenetic/behaviors/alternate_string_identifier'

class Frenetic
module Behaviors
end
end
55 changes: 55 additions & 0 deletions lib/frenetic/behaviors/alternate_string_identifier.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Allows a resource to be found by a string-based alternative key
#
# For example
#
# module MyClient
# module MyResource < Frenetic::Resource
# extend Frenetic::Behaviors::AlternateStringIdentifier
#
# def self.find(id)
# super(finder_params(id, :username))
# end
# end
# end
#
# Given an Api Schema such as:
#
# {
# _links: {
# my_resource: [{
# { href: '/api/my_resource/{id}', rel: 'id' },
# { href: '/api/my_resource/{username}?specific_to=username', rel: 'username' },
# }]
# }
# }
#
# MyClient::MyResource.find will choose the alternate link relation based on
# the string-based ID passed in.
#
# MyClient::MyResource.find(1)
# # Executes /api/my_resource/1
#
# MyClient::MyResource.find('100')
# # Executes /api/my_resource/100
#
# MyClient::MyResource.find('jdoe')
# Executes /api/my_resource/jdoe?specific_to=username
#
class Frenetic
module Behaviors
module AlternateStringIdentifier
def finder_params(unique_id, alternate_key)
return unique_id if unique_id.is_a? Hash
params = {}
key = nil
if unique_id.to_i.to_s == unique_id.to_s
key = :id
elsif !unique_id.nil?
key = alternate_key
end
params[key] = unique_id
params
end
end
end
end
44 changes: 44 additions & 0 deletions spec/behaviors/alternate_string_identifier_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require 'spec_helper'

describe Frenetic::Behaviors::AlternateStringIdentifier do
let(:my_temp_resource) do
Class.new(Frenetic::Resource)
end

before do
stub_const 'MyTempResource', my_temp_resource
MyTempResource.send(:extend, described_class)
end

describe '.finder_params' do
let(:id) { }
let(:alternate_key) { }

subject { MyTempResource.finder_params(id, alternate_key) }

context 'with a Fixnum identifier' do
let(:id) { 1 }

it 'uses :id for the finder key' do
expect(subject).to include id:id
end
end

context 'with a String identifier representing a Fixnum' do
let(:id) { '100' }

it 'uses :id for the finder key' do
expect(subject).to include id:id
end
end

context 'with a String identifier' do
let(:id) { 'foo' }
let(:alternate_key) { 'alt' }

it 'uses :id for the finder key' do
expect(subject).to include 'alt' => id
end
end
end
end

0 comments on commit 480ea5a

Please sign in to comment.