Skip to content
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ spec/reports
test/tmp
test/version_tmp
tmp
.idea/
42 changes: 22 additions & 20 deletions lib/oat/adapters/siren.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# frozen_string_literal: true

# https://github.com/kevinswiber/siren
module Oat
module Adapters
class Siren < Oat::Adapter

def initialize(*args)
super
data[:links] = []
Expand All @@ -12,17 +13,21 @@ def initialize(*args)

# Sub-Entities have a required rel attribute
# https://github.com/kevinswiber/siren#rel
def rel(rels)
def rel(*rels)
# rel must be an array.
data[:rel] = Array(rels)
end

def type(*types)
data[:class] = types
data[:class] = Array(types)
end

def title(title)
data[:title] = title
end

def link(rel, opts = {})
data[:links] << {:rel => [rel].flatten}.merge(opts)
data[:links] << { rel: Array(rel) }.merge(opts)
end

def properties(&block)
Expand All @@ -33,7 +38,7 @@ def property(key, value)
data[:properties][key] = value
end

alias_method :meta, :property
alias meta property

def entity(name, obj, serializer_class = nil, context_options = {}, &block)
ent = serializer_from_block_or_class(obj, serializer_class, context_options, &block)
Expand All @@ -42,9 +47,7 @@ def entity(name, obj, serializer_class = nil, context_options = {}, &block)
ent.rel(name)
ent_hash = ent.to_hash

unless data[:entities].include? ent_hash
data[:entities] << ent_hash
end
data[:entities] << ent_hash
end
end

Expand All @@ -54,11 +57,11 @@ def entities(name, collection, serializer_class = nil, context_options = {}, &bl
end
end

alias_method :collection, :entities
alias collection entities

def action(name, &block)
def action(name)
action = Action.new(name)
block.call(action)
yield(action)

data[:actions] << action.data
end
Expand All @@ -67,21 +70,21 @@ class Action
attr_reader :data

def initialize(name)
@data = { :name => name, :class => [], :fields => [] }
@data = { name: name, class: [], fields: [] }
end

def klass(value)
data[:class] << value
data[:class].concat(Array(value))
end

def field(name, &block)
def field(name)
field = Field.new(name)
block.call(field)
yield(field)

data[:fields] << field.data
end

%w(href method title type).each do |attribute|
%w[categories href method title type].each do |attribute|
define_method(attribute) do |value|
data[attribute.to_sym] = value
end
Expand All @@ -91,21 +94,20 @@ class Field
attr_reader :data

def initialize(name)
@data = { :name => name, :class => []}
@data = { name: name, class: [] }
end

def klass(value)
data[:class] << value
data[:class].concat(Array(value))
end

%w(type value title).each do |attribute|
%w[category type value title].each do |attribute|
define_method(attribute) do |value|
data[attribute.to_sym] = value
end
end
end
end

end
end
end
2 changes: 2 additions & 0 deletions spec/adapters/siren_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
it 'produces a Siren-compliant hash' do
expect(hash.fetch(:class)).to match_array(['user'])

expect(hash.fetch(:title)).to eq('This guy')

expect(hash.fetch(:properties)).to include(
:id => user.id,
:name => user.name,
Expand Down
4 changes: 4 additions & 0 deletions spec/fixtures.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ def self.included(base)
entities [:friends, 'http://example.org/rels/person'], item.friends, klass, :message => "Merged into parent's context"
end

if adapter.respond_to?(:title)
title 'This guy'
end

if adapter.respond_to?(:action)
action :close_account do |action|
action.href "http://foo.bar.com/#{item.id}/close_account"
Expand Down