cyrax 0.5.13 → 0.6.0.beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +14 -6
- data/lib/cyrax.rb +2 -9
- data/lib/cyrax/decorator.rb +0 -17
- data/lib/cyrax/extensions/has_decorator.rb +9 -9
- data/lib/cyrax/extensions/has_repository.rb +43 -0
- data/lib/cyrax/extensions/has_resource.rb +23 -32
- data/lib/cyrax/extensions/has_response.rb +0 -1
- data/lib/cyrax/extensions/has_serializer.rb +9 -9
- data/lib/cyrax/extensions/has_service.rb +26 -59
- data/lib/cyrax/helpers/controller.rb +1 -1
- data/lib/cyrax/presenter.rb +1 -1
- data/lib/cyrax/repository.rb +102 -0
- data/lib/cyrax/resource.rb +1 -0
- data/lib/cyrax/response.rb +3 -8
- data/lib/cyrax/serializer.rb +0 -27
- data/lib/cyrax/serializers/scope.rb +4 -18
- data/lib/cyrax/version.rb +1 -1
- data/spec/cyrax/extensions/has_decorator_spec.rb +5 -5
- data/spec/cyrax/extensions/has_repository_spec.rb +28 -0
- data/spec/cyrax/extensions/has_resource_spec.rb +6 -15
- data/spec/cyrax/extensions/has_response_spec.rb +1 -1
- data/spec/cyrax/extensions/has_service_spec.rb +0 -43
- data/spec/cyrax/repository_spec.rb +72 -0
- data/spec/cyrax/resource_spec.rb +21 -35
- data/spec/cyrax/serializer_spec.rb +2 -13
- metadata +28 -36
data/lib/cyrax/presenter.rb
CHANGED
@@ -20,7 +20,7 @@ class Cyrax::Presenter < Cyrax::Wrapper
|
|
20
20
|
if options[:present] == :collection
|
21
21
|
Cyrax::Presenters::DecoratedCollection.new(resource, options)
|
22
22
|
else
|
23
|
-
options[:decorator].decorate(resource
|
23
|
+
options[:decorator].decorate(resource)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -0,0 +1,102 @@
|
|
1
|
+
class Cyrax::Repository
|
2
|
+
include HasActiveLogger::Mixin
|
3
|
+
attr_accessor :options
|
4
|
+
attr_accessor :accessor
|
5
|
+
attr_accessor :params
|
6
|
+
attr_accessor :resource_class
|
7
|
+
attr_accessor :finder_blocks
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
@options = options
|
11
|
+
@accessor = options[:as]
|
12
|
+
@params = options[:params]
|
13
|
+
@resource_class = options[:resource_class]
|
14
|
+
@finder_blocks = options[:finder_blocks] || {}
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns the resource class - e.g. Product by default.
|
18
|
+
# If you want your repository to scope with something interesting,
|
19
|
+
# you should override this in your repository by defining the method and returning your own scope
|
20
|
+
#
|
21
|
+
# @example Overriding scope
|
22
|
+
# class Products::Repository < Cyrax::Repository
|
23
|
+
# def scope
|
24
|
+
# accessor.products
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
def scope
|
28
|
+
if block = finder_blocks[:scope]
|
29
|
+
instance_exec(&block)
|
30
|
+
else
|
31
|
+
resource_class
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Instantiates the resource
|
36
|
+
# @param id [int] ID or nil if you want a new object
|
37
|
+
# @param attributes [hash] Attributes you want to add to the resource
|
38
|
+
# @return [object] The object
|
39
|
+
def build(id, attributes = {})
|
40
|
+
if block = finder_blocks[:build]
|
41
|
+
instance_exec(id, attributes, &block)
|
42
|
+
else
|
43
|
+
if id.present?
|
44
|
+
resource = find(id)
|
45
|
+
resource.attributes = attributes
|
46
|
+
resource
|
47
|
+
else
|
48
|
+
scope.new(default_attributes.merge(attributes))
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Finds and returns a multiple items within the scope from the DB
|
54
|
+
# @return [Array] Array of objects
|
55
|
+
def find_all
|
56
|
+
if block = finder_blocks[:find_all]
|
57
|
+
instance_exec(&block)
|
58
|
+
else
|
59
|
+
scope.is_a?(ActiveRecord::Relation) ? scope.load : scope.all
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Finds and returns a single item from the DB
|
64
|
+
# @param id [int] ID of item
|
65
|
+
# @return [object] The object
|
66
|
+
def find(id)
|
67
|
+
if block = finder_blocks[:find]
|
68
|
+
instance_exec(id, &block)
|
69
|
+
else
|
70
|
+
scope.find(id)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Saves a resource
|
75
|
+
# @param resource [object] The resource to save
|
76
|
+
def save(resource)
|
77
|
+
if block = finder_blocks[:save]
|
78
|
+
instance_exec(resource, &block)
|
79
|
+
else
|
80
|
+
resource.save
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Removes a resource
|
85
|
+
# Calls destroy method on resource
|
86
|
+
# @param resource [object] The resource to destroy
|
87
|
+
def delete(resource)
|
88
|
+
if block = finder_blocks[:delete]
|
89
|
+
instance_exec(resource, &block)
|
90
|
+
else
|
91
|
+
resource.destroy
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def default_attributes
|
96
|
+
if block = finder_blocks[:default_attributes]
|
97
|
+
instance_exec(&block)
|
98
|
+
else
|
99
|
+
{}
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
data/lib/cyrax/resource.rb
CHANGED
data/lib/cyrax/response.rb
CHANGED
@@ -55,19 +55,14 @@ class Cyrax::Response
|
|
55
55
|
if failure?
|
56
56
|
{errors: @errors}
|
57
57
|
elsif options[:serializer]
|
58
|
-
options[:serializer].new(result,
|
58
|
+
options[:serializer].new(result, as: accessor).serialize
|
59
59
|
else
|
60
60
|
result.as_json
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
64
|
def method_missing(method, *args, &block)
|
65
|
-
|
66
|
-
|
67
|
-
elsif assignments.has_key?(method)
|
68
|
-
assignments[method]
|
69
|
-
else
|
70
|
-
super
|
71
|
-
end
|
65
|
+
super unless assignments.has_key?(method)
|
66
|
+
assignments[method]
|
72
67
|
end
|
73
68
|
end
|
data/lib/cyrax/serializer.rb
CHANGED
@@ -1,45 +1,18 @@
|
|
1
1
|
class Cyrax::Serializer < Cyrax::Wrapper
|
2
2
|
def serialize
|
3
3
|
options[:serializer] = self
|
4
|
-
|
5
|
-
if block = self.class.total_count_block
|
6
|
-
serialize_wrapped(options, &block)
|
7
|
-
else
|
8
|
-
serialize_simple(options)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
def serialize_simple(options = {})
|
13
4
|
self.class.scope.serialize(resource, options)
|
14
5
|
end
|
15
6
|
|
16
|
-
def serialize_wrapped(options = {}, &counter_block)
|
17
|
-
total_count = self.instance_eval(&counter_block)
|
18
|
-
data = self.class.scope.serialize(resource, options)
|
19
|
-
{total_count: total_count, data: data}
|
20
|
-
end
|
21
|
-
|
22
7
|
class << self
|
23
8
|
def scope
|
24
9
|
@scope ||= Cyrax::Serializers::Scope.new()
|
25
10
|
end
|
26
11
|
|
27
|
-
def total_count(&block)
|
28
|
-
@total_count_block = block
|
29
|
-
end
|
30
|
-
|
31
|
-
def total_count_block
|
32
|
-
@total_count_block
|
33
|
-
end
|
34
|
-
|
35
12
|
def namespace(name, &block)
|
36
13
|
scope.namespace(name, &block)
|
37
14
|
end
|
38
15
|
|
39
|
-
def assigned(name, &block)
|
40
|
-
scope.assigned(name, &block)
|
41
|
-
end
|
42
|
-
|
43
16
|
def relation(name, &block)
|
44
17
|
scope.relation(name, &block)
|
45
18
|
end
|
@@ -5,7 +5,6 @@ module Cyrax::Serializers
|
|
5
5
|
@dynamic_attrs = {}
|
6
6
|
@relation_attrs = {}
|
7
7
|
@namespace_attrs = {}
|
8
|
-
@assigned_attrs = {}
|
9
8
|
@default_attributes = false
|
10
9
|
instance_eval(&block) if block_given?
|
11
10
|
end
|
@@ -14,10 +13,6 @@ module Cyrax::Serializers
|
|
14
13
|
@namespace_attrs[name] = self.class.new(&block)
|
15
14
|
end
|
16
15
|
|
17
|
-
def assigned(name, &block)
|
18
|
-
@assigned_attrs[name] = self.class.new(&block)
|
19
|
-
end
|
20
|
-
|
21
16
|
def relation(attribute, &block)
|
22
17
|
if block_given?
|
23
18
|
@relation_attrs[attribute] = self.class.new(&block)
|
@@ -25,8 +20,6 @@ module Cyrax::Serializers
|
|
25
20
|
@attrs[attribute] = attribute
|
26
21
|
end
|
27
22
|
end
|
28
|
-
alias_method :has_many, :relation
|
29
|
-
alias_method :has_one, :relation
|
30
23
|
|
31
24
|
def default_attributes
|
32
25
|
@default_attributes = true
|
@@ -47,9 +40,7 @@ module Cyrax::Serializers
|
|
47
40
|
end
|
48
41
|
|
49
42
|
def serialize(resource, options = {})
|
50
|
-
if resource.
|
51
|
-
nil
|
52
|
-
elsif resource.respond_to?(:to_a)
|
43
|
+
if resource.respond_to?(:to_a)
|
53
44
|
resource.to_a.map{ |r| serialize_one(r, options) }
|
54
45
|
else
|
55
46
|
serialize_one(resource, options)
|
@@ -62,19 +53,14 @@ module Cyrax::Serializers
|
|
62
53
|
result = resource.attributes rescue {}
|
63
54
|
end
|
64
55
|
@dynamic_attrs.map do |attribute, block|
|
65
|
-
result[attribute] = options[:serializer].instance_exec(resource,
|
56
|
+
result[attribute] = options[:serializer].instance_exec(resource, &block)
|
66
57
|
end
|
67
58
|
@relation_attrs.map do |attribute, scope|
|
68
59
|
value = resource.send(attribute)
|
69
|
-
result[attribute] = scope.serialize(value
|
70
|
-
end
|
71
|
-
@assigned_attrs.map do |attribute, scope|
|
72
|
-
assignments = options[:assignments] || {}
|
73
|
-
value = assignments[attribute]
|
74
|
-
result[attribute] = scope.serialize(value, options)
|
60
|
+
result[attribute] = scope.serialize(value)
|
75
61
|
end
|
76
62
|
@namespace_attrs.map do |attribute, scope|
|
77
|
-
result[attribute] = scope.serialize(resource
|
63
|
+
result[attribute] = scope.serialize(resource)
|
78
64
|
end
|
79
65
|
@attrs.map do |attribute, options|
|
80
66
|
result[attribute] = resource.send(attribute)
|
data/lib/cyrax/version.rb
CHANGED
@@ -20,26 +20,26 @@ module Cyrax
|
|
20
20
|
subject { BaseWithDecorator.new }
|
21
21
|
|
22
22
|
describe 'class attributes' do
|
23
|
-
its(:class) { should respond_to(:
|
23
|
+
its(:class) { should respond_to(:_decorator_class) }
|
24
24
|
end
|
25
25
|
|
26
26
|
describe 'class methods' do
|
27
27
|
describe '#decorator' do
|
28
|
-
before { subject.class.decorator(
|
28
|
+
before { subject.class.decorator(Foo) }
|
29
29
|
|
30
|
-
its(:
|
30
|
+
its(:decorator_class) { should eq(Foo) }
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
34
|
describe 'instance methods' do
|
35
35
|
describe '#decorator_class' do
|
36
|
-
before { subject.class.decorator(
|
36
|
+
before { subject.class.decorator(Foo) }
|
37
37
|
its(:decorator_class) { should eq(Foo) }
|
38
38
|
end
|
39
39
|
|
40
40
|
describe '#decorable?' do
|
41
41
|
context 'when `decorator_class_name` present' do
|
42
|
-
before { subject.class.decorator(
|
42
|
+
before { subject.class.decorator(Foo) }
|
43
43
|
its(:decorable?) { should be_true }
|
44
44
|
end
|
45
45
|
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class Bar; end
|
4
|
+
class Foo; end
|
5
|
+
|
6
|
+
module Cyrax
|
7
|
+
class BaseWithRepository < Cyrax::Base
|
8
|
+
include Cyrax::Extensions::HasRepository
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Cyrax::Extensions::HasRepository do
|
12
|
+
subject { BaseWithRepository.new }
|
13
|
+
|
14
|
+
describe 'class attributes' do
|
15
|
+
its(:class) { should respond_to(:_repository_class) }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'class methods' do
|
19
|
+
describe '#repository' do
|
20
|
+
context "define repository class" do
|
21
|
+
before { subject.class.repository(Foo) }
|
22
|
+
|
23
|
+
its(:repository_class) { should eq(Foo) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -18,16 +18,17 @@ module Cyrax
|
|
18
18
|
subject { BaseWithResource.new }
|
19
19
|
|
20
20
|
describe 'class attributes' do
|
21
|
-
its(:class) { should respond_to(:
|
22
|
-
its(:class) { should respond_to(:
|
21
|
+
its(:class) { should respond_to(:_resource_name) }
|
22
|
+
its(:class) { should respond_to(:_collection_name) }
|
23
|
+
its(:class) { should respond_to(:_resource_class) }
|
23
24
|
end
|
24
25
|
|
25
26
|
describe 'class methods' do
|
26
27
|
describe '#resource' do
|
27
|
-
before { subject.class.resource(:foo,
|
28
|
+
before { subject.class.resource(:foo, class: Bar, name:'bazz') }
|
28
29
|
|
29
30
|
its(:resource_name) { should eq('foo') }
|
30
|
-
its(:
|
31
|
+
its(:resource_class) { should eq(Bar) }
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
@@ -45,7 +46,7 @@ module Cyrax
|
|
45
46
|
|
46
47
|
describe '#resource_class' do
|
47
48
|
context 'when `class_name` option is supplied' do
|
48
|
-
before { subject.class.resource(:foo,
|
49
|
+
before { subject.class.resource(:foo, class: Bar) }
|
49
50
|
its(:resource_class) { should eq(Bar) }
|
50
51
|
end
|
51
52
|
|
@@ -55,11 +56,6 @@ module Cyrax
|
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|
58
|
-
describe '#resource_scope' do
|
59
|
-
before { subject.stub(:resource_class).and_return(Foo) }
|
60
|
-
its(:resource_scope) { should eq(Foo) }
|
61
|
-
end
|
62
|
-
|
63
59
|
describe '#resource_attributes' do
|
64
60
|
let(:dirty_resource_attributes) { double }
|
65
61
|
before { subject.stub(:dirty_resource_attributes).and_return(dirty_resource_attributes)}
|
@@ -88,11 +84,6 @@ module Cyrax
|
|
88
84
|
end
|
89
85
|
end
|
90
86
|
end
|
91
|
-
describe '#default_resource_attributes' do
|
92
|
-
it 'should return empty hash by default' do
|
93
|
-
subject.send(:default_resource_attributes).should eq({})
|
94
|
-
end
|
95
|
-
end
|
96
87
|
|
97
88
|
describe '#filter_attributes' do
|
98
89
|
it 'should return supplied attributes by default' do
|
@@ -59,7 +59,7 @@ module Cyrax
|
|
59
59
|
describe '#respond_with' do
|
60
60
|
before { subject.stub(:response_name).and_return(:foo) }
|
61
61
|
it 'calls Cyrax::Response' do
|
62
|
-
Cyrax::Response.should_receive(:new).with(:foo, 'bar', {as: nil
|
62
|
+
Cyrax::Response.should_receive(:new).with(:foo, 'bar', {as: nil}).and_return(double.as_null_object)
|
63
63
|
subject.respond_with('bar')
|
64
64
|
end
|
65
65
|
|
@@ -16,48 +16,5 @@ module Cyrax
|
|
16
16
|
|
17
17
|
describe Cyrax::Extensions::HasResource do
|
18
18
|
subject { BaseWithService.new }
|
19
|
-
|
20
|
-
describe 'instance methods' do
|
21
|
-
describe '#build_collection' do
|
22
|
-
before { subject.stub(:resource_scope).and_return(Foo) }
|
23
|
-
its(:build_collection) { should eq(Foo) }
|
24
|
-
end
|
25
|
-
|
26
|
-
describe '#find_resource' do
|
27
|
-
let(:resource_scope) { double }
|
28
|
-
before { subject.stub(:resource_scope).and_return(resource_scope) }
|
29
|
-
it 'finds resource by id' do
|
30
|
-
allow_message_expectations_on_nil
|
31
|
-
resource_scope.should_receive(:find).with(123)
|
32
|
-
subject.find_resource(123)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
describe '#build_resource' do
|
37
|
-
context 'when id is nil' do
|
38
|
-
let(:resource_scope) { double }
|
39
|
-
before { subject.stub(:resource_scope).and_return(resource_scope) }
|
40
|
-
before { subject.stub(:default_resource_attributes).and_return({}) }
|
41
|
-
it 'initializes new object' do
|
42
|
-
allow_message_expectations_on_nil
|
43
|
-
resource_scope.should_receive(:new).with({foo: 'bar'})
|
44
|
-
subject.build_resource(nil, {foo: 'bar'})
|
45
|
-
end
|
46
|
-
end
|
47
|
-
context 'when id is present' do
|
48
|
-
let(:resource) { double.as_null_object }
|
49
|
-
it 'finds resource' do
|
50
|
-
subject.should_receive(:find_resource).with(123).and_return(resource)
|
51
|
-
subject.build_resource(123, {foo: 'bar'})
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'assigns provided attributes' do
|
55
|
-
subject.stub(:find_resource).and_return(resource)
|
56
|
-
resource.should_receive(:attributes=).with({foo: 'bar'})
|
57
|
-
subject.build_resource(123, {foo: 'bar'})
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
19
|
end
|
63
20
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class Foo; end
|
4
|
+
module Cyrax
|
5
|
+
describe Repository do
|
6
|
+
describe 'it should behave like repository' do
|
7
|
+
context 'instance methods' do
|
8
|
+
subject { Cyrax::Repository.new }
|
9
|
+
it{ should respond_to(:resource_class) }
|
10
|
+
it{ should respond_to(:scope) }
|
11
|
+
it{ should respond_to(:build) }
|
12
|
+
it{ should respond_to(:find_all) }
|
13
|
+
it{ should respond_to(:find) }
|
14
|
+
it{ should respond_to(:save) }
|
15
|
+
it{ should respond_to(:delete) }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'instance methods' do
|
20
|
+
describe '#find_all' do
|
21
|
+
let(:scope) { double }
|
22
|
+
before { subject.stub(:scope).and_return(scope) }
|
23
|
+
it 'finds all objects by default' do
|
24
|
+
scope.should_receive(:all)
|
25
|
+
subject.find_all
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#find_resource' do
|
30
|
+
let(:scope) { double }
|
31
|
+
before { subject.stub(:scope).and_return(scope) }
|
32
|
+
it 'finds resource by id' do
|
33
|
+
allow_message_expectations_on_nil
|
34
|
+
scope.should_receive(:find).with(123)
|
35
|
+
subject.find(123)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#build_resource' do
|
40
|
+
context 'when id is nil' do
|
41
|
+
let(:scope) { double }
|
42
|
+
before { subject.stub(:scope).and_return(scope) }
|
43
|
+
before { subject.stub(:default_attributes).and_return({}) }
|
44
|
+
it 'initializes new object' do
|
45
|
+
allow_message_expectations_on_nil
|
46
|
+
scope.should_receive(:new).with({foo: 'bar'})
|
47
|
+
subject.build(nil, {foo: 'bar'})
|
48
|
+
end
|
49
|
+
end
|
50
|
+
context 'when id is present' do
|
51
|
+
let(:resource) { double.as_null_object }
|
52
|
+
it 'finds resource' do
|
53
|
+
subject.should_receive(:find).with(123).and_return(resource)
|
54
|
+
subject.build(123, {foo: 'bar'})
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'assigns provided attributes' do
|
58
|
+
subject.stub(:find).and_return(resource)
|
59
|
+
resource.should_receive(:attributes=).with({foo: 'bar'})
|
60
|
+
subject.build(123, {foo: 'bar'})
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#default_attributes' do
|
66
|
+
it 'should return empty hash by default' do
|
67
|
+
subject.send(:default_attributes).should eq({})
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|