cyrax 0.7.7 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 043a9c1603e71223e2afbbd9154f56e6b5fcddbe
4
- data.tar.gz: 0c96ab2707143c9eaff37bf9458dc6926b5d3f49
2
+ SHA256:
3
+ metadata.gz: 468b7482d42c779907d5f69afd25057120a2f9f3a88d5701dda02e14e2789fc5
4
+ data.tar.gz: 3f42ca73dda52d2dbfcaebfd067aeb8b151fe8eb8e34e65f238b7d8ff17565bb
5
5
  SHA512:
6
- metadata.gz: b9aa5a859dfbd6529352cc731cfa95da99fac22285fdac709c7c006628767704e3e659c9ff41781996b4fdf363a91648edae1f8d1e5670683ff42a4e48e87bbd
7
- data.tar.gz: 7cb5f606fe2a9df4c09a63ff9336a42be73ba1460f35b8e4e987d4118cec9ad19a42758cc14891b8175452419d4fe1fee1e34bf7467c23d4d6ecbfaadcdcf76c
6
+ metadata.gz: 815a0c1ab08bd9d714c4003b8be967a2ad6c506fb95726b87111f8fdda29d0197589b6f75a881e9aa1def6c28c5b87f4a39bfc888725f6afc82e9d33741f7547
7
+ data.tar.gz: c64d11365bd3a6534a6ec338e64005a7dc74a3c8295685ba1699f3702b01ac20042f20ef39dce75b0850c1f2d8ccb580466e0fd5bec8ac4ca1c0886b74a5c3b7
data/README.md CHANGED
@@ -1,6 +1,4 @@
1
- # Cyrax [![Build Status](https://travis-ci.org/droidlabs/cyrax.png)](https://travis-ci.org/droidlabs/cyrax) [![Code Climate](https://codeclimate.com/github/droidlabs/cyrax.png)](https://codeclimate.com/github/droidlabs/cyrax) [![Roadchange](http://roadchange.com/droidlabs/cyrax/badge.png)](http://roadchange.com/droidlabs/cyrax)
2
- ![Cyrax](http://images2.wikia.nocookie.net/__cb20121118042055/mk/images/thumb/4/44/CyraxMK9Render.png/322px-CyraxMK9Render.png)
3
- > Safeties disabled; combat mode engaged.
1
+ # Cyrax [![Build Status](https://travis-ci.org/droidlabs/cyrax.png)](https://travis-ci.org/droidlabs/cyrax) [![Code Climate](https://codeclimate.com/github/droidlabs/cyrax.png)](https://codeclimate.com/github/droidlabs/cyrax)
4
2
 
5
3
  Cyrax is microframework to build layered architecture, one of the core concepts of Domain Driven Design
6
4
 
@@ -8,13 +6,13 @@ Cyrax is microframework to build layered architecture, one of the core concepts
8
6
 
9
7
  Add this line to your Gemfile.
10
8
 
11
- Rails 4:
9
+ Rails 5:
12
10
 
13
- gem 'cyrax', '~> 0.7.6'
11
+ gem 'cyrax', '~> 0.9.0'
14
12
 
15
- Rails 3:
13
+ Rails 4:
16
14
 
17
- gem 'cyrax', '~> 0.3.8'
15
+ gem 'cyrax', '~> 0.5.0'
18
16
 
19
17
  ## Usage
20
18
 
@@ -1,4 +1,6 @@
1
1
  require 'active_model'
2
+ require 'active_model/serializers/xml'
3
+
2
4
  class Cyrax::Decorator < Cyrax::Wrapper
3
5
  include ActiveModel::Serialization
4
6
  include ActiveModel::Serializers::JSON
@@ -31,5 +33,18 @@ class Cyrax::Decorator < Cyrax::Wrapper
31
33
  def decorate_collection(resource)
32
34
  Cyrax::Presenters::DecoratedCollection.decorate(resource, decorator: self)
33
35
  end
36
+
37
+ def respond_to?(method_sym, include_private = false)
38
+ super || @@decorated_class.respond_to?(method_sym, include_private)
39
+ end
40
+
41
+ def method_missing(method, *args, &block)
42
+ return super unless @@decorated_class.respond_to?(method)
43
+ @@decorated_class.send(method, *args, &block)
44
+ end
45
+
46
+ def decorated_class(klass)
47
+ @@decorated_class = klass
48
+ end
34
49
  end
35
50
  end
@@ -3,24 +3,24 @@ module Cyrax::Extensions
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
- class_attribute :_decorator_class
6
+ class_attribute :decorator_class_name
7
+ end
8
+
9
+ def decorator_class_name
10
+ options[:decorator] || self.class.decorator_class_name
7
11
  end
8
12
 
9
13
  def decorable?
10
- !decorator_class.nil?
14
+ !decorator_class_name.nil?
11
15
  end
12
16
 
13
17
  def decorator_class
14
- options[:decorator] || self.class._decorator_class
18
+ decorator_class_name.to_s.classify.constantize
15
19
  end
16
20
 
17
21
  module ClassMethods
18
- def decorator(klass)
19
- if klass.is_a?(String)
20
- ActiveSupport::Deprecation.warn "sending String in #decorator method is deprecated. send Class instead"
21
- klass = klass.constantize
22
- end
23
- self._decorator_class = klass
22
+ def decorator(name)
23
+ self.decorator_class_name = name ? name.to_s : nil
24
24
  end
25
25
  end
26
26
  end
@@ -4,28 +4,41 @@ module Cyrax::Extensions
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
7
- class_attribute :_resource_name
8
- class_attribute :_collection_name
9
- class_attribute :_resource_class
10
- end
11
-
12
- def resource_name
13
- self.class._resource_name
14
- end
15
-
16
- def collection_name
17
- self.class._collection_name
7
+ class_attribute :resource_name
8
+ class_attribute :resource_class_name
9
+ class_attribute :collection_name
18
10
  end
19
11
 
20
12
  # Returns the resource class as a constant - e.g. Product
21
13
  def resource_class
22
- self.class._resource_class || resource_name.classify.constantize
14
+ if self.resource_class_name
15
+ self.resource_class_name.constantize
16
+ else
17
+ resource_name.classify.constantize
18
+ end
19
+ end
20
+
21
+ # Returns the resource class - e.g. Product
22
+ # If you want your resource to return something interesting, you should override this in your resource by defining the method and returning your own scope
23
+ #
24
+ # @example Overriding resource_scope
25
+ # class Products::UserResource < Products::BaseResource
26
+ # def resource_scope
27
+ # accessor.products
28
+ # end
29
+ # end
30
+ def resource_scope
31
+ resource_class
23
32
  end
24
33
 
25
34
  def resource_attributes
26
35
  filter_attributes(dirty_resource_attributes)
27
36
  end
28
37
 
38
+ def response_name
39
+ resource_name
40
+ end
41
+
29
42
  module ClassMethods
30
43
 
31
44
  # Class method for setting all the attributes that you want to access in the resource
@@ -51,21 +64,13 @@ module Cyrax::Extensions
51
64
  # @param name [Symbol] The name of the resource
52
65
  # @param options Hash [Hash] Options
53
66
  def resource(name, options = {})
54
- if options[:class_name].present?
55
- ActiveSupport::Deprecation.warn "sending :class_name in #resource method is deprecated. send :class instead"
56
- options[:class] = options[:class_name].to_s.constantize
57
- end
58
- self._resource_name = name.to_s
59
- self._resource_class = options[:class]
60
- self._collection_name = name.to_s.pluralize
67
+ self.resource_name = name.to_s
68
+ self.resource_class_name = options[:class_name]
69
+ self.collection_name = name.to_s.pluralize
61
70
  end
62
71
  end
63
72
 
64
73
  private
65
- def response_name
66
- resource_name
67
- end
68
-
69
74
  def dirty_resource_attributes
70
75
  if Cyrax.strong_parameters
71
76
  params.require(resource_name)
@@ -74,6 +79,10 @@ module Cyrax::Extensions
74
79
  end
75
80
  end
76
81
 
82
+ def default_resource_attributes
83
+ {}
84
+ end
85
+
77
86
  def filter_attributes(attributes)
78
87
  if Cyrax.strong_parameters
79
88
  attributes.permit(self.class.accessible_attributes)
@@ -3,24 +3,24 @@ module Cyrax::Extensions
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
- class_attribute :_serializer_class
6
+ class_attribute :serializer_class_name
7
+ end
8
+
9
+ def serializer_class_name
10
+ options[:serializer] || self.class.serializer_class_name
7
11
  end
8
12
 
9
13
  def serializable?
10
- !serializer_class.nil?
14
+ !serializer_class_name.nil?
11
15
  end
12
16
 
13
17
  def serializer_class
14
- options[:serializer] || self.class._serializer_class
18
+ serializer_class_name.to_s.classify.constantize
15
19
  end
16
20
 
17
21
  module ClassMethods
18
- def serializer(klass)
19
- if klass.is_a?(String)
20
- ActiveSupport::Deprecation.warn "sending String in #serializer method is deprecated. send Class instead"
21
- klass = klass.constantize
22
- end
23
- self._serializer_class = klass
22
+ def serializer(name)
23
+ self.serializer_class_name = name ? name.to_s : nil
24
24
  end
25
25
  end
26
26
  end
@@ -1,15 +1,17 @@
1
1
  module Cyrax::Extensions
2
2
  module HasService
3
+ VALIDATION_ERROR_STATUS = 422
3
4
  extend ActiveSupport::Concern
4
5
 
5
6
  # Builds and returns a collection response for Rails
6
7
  # @return [Cyrax::Response] response
7
8
  def read_all(&block)
8
9
  authorize_resource!(:read_all, resource_class)
9
- collection = repository.find_all
10
+ collection = build_collection
10
11
  block.call(collection) if block_given?
11
12
  respond_with collection, name: collection_name, present: :collection
12
13
  end
14
+ # Overrides collection with read_all
13
15
  alias_method :read_all!, :read_all
14
16
 
15
17
  # Builds a new resource without saving to DB
@@ -17,7 +19,7 @@ module Cyrax::Extensions
17
19
  # Used for :new action in controller
18
20
  # @return [Cyrax::Response] response
19
21
  def build(&block)
20
- resource = repository.build(nil)
22
+ resource = build_resource(nil)
21
23
  authorize_resource!(:build, resource)
22
24
  block.call(resource) if block_given?
23
25
  respond_with resource
@@ -28,14 +30,14 @@ module Cyrax::Extensions
28
30
  # Used for :create action in controller
29
31
  # @return [Cyrax::Response] response
30
32
  def create(custom_attributes = nil, &block)
31
- resource = repository.build(nil)
32
- old_resource = resource.dup
33
- set_resource_attributes(resource, custom_attributes||resource_attributes)
33
+ resource = build_resource(nil, custom_attributes||resource_attributes)
34
34
  authorize_resource!(:create, resource)
35
35
  transaction do
36
- if repository.save(resource)
36
+ if save_resource(resource)
37
37
  set_message(:created)
38
- block.call(resource, old_resource) if block_given?
38
+ block.call(resource) if block_given?
39
+ elsif Cyrax.automatically_set_invalid_status
40
+ set_status VALIDATION_ERROR_STATUS
39
41
  end
40
42
  end
41
43
  respond_with(resource)
@@ -46,7 +48,7 @@ module Cyrax::Extensions
46
48
  # Used for :show action in controller
47
49
  # @return [Cyrax::Response] response
48
50
  def read(&block)
49
- resource = repository.find(resource_params_id)
51
+ resource = find_resource(resource_params_id)
50
52
  block.call(resource) if block_given?
51
53
  respond_with resource
52
54
  end
@@ -58,14 +60,14 @@ module Cyrax::Extensions
58
60
  # Used for :update action in controller
59
61
  # @return [Cyrax::Response] response
60
62
  def update(custom_attributes = nil, &block)
61
- resource = repository.build(resource_params_id)
62
- old_resource = resource.dup
63
- set_resource_attributes(resource, custom_attributes||resource_attributes)
63
+ resource = build_resource(resource_params_id, custom_attributes||resource_attributes)
64
64
  authorize_resource!(:update, resource)
65
65
  transaction do
66
- if repository.save(resource)
66
+ if save_resource(resource)
67
67
  set_message(:updated)
68
- block.call(resource, old_resource) if block_given?
68
+ block.call(resource) if block_given?
69
+ elsif Cyrax.automatically_set_invalid_status
70
+ set_status VALIDATION_ERROR_STATUS
69
71
  end
70
72
  end
71
73
  respond_with(resource)
@@ -76,16 +78,50 @@ module Cyrax::Extensions
76
78
  # Used for :destroy action in controller
77
79
  # @return [Cyrax::Response] response
78
80
  def destroy(&block)
79
- resource = repository.find(resource_params_id)
81
+ resource = find_resource(resource_params_id)
80
82
  authorize_resource!(:destroy, resource)
81
83
  transaction do
82
- repository.delete(resource)
84
+ delete_resource(resource)
83
85
  block.call(resource) if block_given?
84
86
  end
85
87
  respond_with(resource)
86
88
  end
87
89
  alias_method :destroy!, :destroy
88
90
 
91
+ # Finds and returns a single item from the DB
92
+ # @param id [int] ID of item
93
+ # @return [object] The object
94
+ def find_resource(id)
95
+ resource_scope.find(id)
96
+ end
97
+
98
+ # Instantiates the resource
99
+ # @param id [int] ID or nil if you want a new object
100
+ # @param attributes [hash] Attributes you want to add to the resource
101
+ # @return [object] The object
102
+ def build_resource(id, attributes = {})
103
+ if id.present?
104
+ resource = find_resource(id)
105
+ resource.attributes = attributes
106
+ resource
107
+ else
108
+ resource_scope.new(default_resource_attributes.merge(attributes))
109
+ end
110
+ end
111
+
112
+ # Saves a resource
113
+ # @param resource [object] The resource to save
114
+ def save_resource(resource)
115
+ resource.save
116
+ end
117
+
118
+ # Remove a resource
119
+ # Calls destroy method on resource
120
+ # @param resource [object] The resource to destroy
121
+ def delete_resource(resource)
122
+ resource.destroy
123
+ end
124
+
89
125
  # Authorize a resource
90
126
  # Should be called on each service method and should be implemented on each resource.
91
127
  # Implementation may raise an exception which may be handled by controller.
@@ -95,6 +131,16 @@ module Cyrax::Extensions
95
131
  # raise AuthorizationError
96
132
  end
97
133
 
134
+ # Returns a collection of the resource we are calling.
135
+ #
136
+ # If you want your resource to return something interesting, you should override the resource_scope method.
137
+ # Otherwise by default it will return the constantized model name and it will call .all on it during presentation.
138
+ #
139
+ # @return [type] The collection
140
+ def build_collection
141
+ resource_scope
142
+ end
143
+
98
144
  def transaction(&block)
99
145
  if defined?(ActiveRecord::Base)
100
146
  ActiveRecord::Base.transaction do
@@ -108,9 +154,5 @@ module Cyrax::Extensions
108
154
  def resource_params_id
109
155
  params[:id]
110
156
  end
111
-
112
- def set_resource_attributes(resource, attributes = {})
113
- resource.attributes = attributes
114
- end
115
157
  end
116
158
  end
@@ -15,7 +15,7 @@ module Cyrax::ControllerHelper
15
15
  result = result.to_model if result.respond_to?(:to_model)
16
16
 
17
17
  respond_to do |format|
18
- format.any do
18
+ format.html do
19
19
  # set flashes
20
20
  if response.success?
21
21
  flash[:notice] = options[:notice] if options[:notice].present?
@@ -27,7 +27,11 @@ module Cyrax::ControllerHelper
27
27
  super(result, options, &block)
28
28
  end
29
29
  format.json do
30
- render json: MultiJson.dump(response.as_json)
30
+ render json: MultiJson.dump(response.as_json), status: options[:status] || 200
31
+ end
32
+ format.any do
33
+ set_resource_from(response)
34
+ super(response, options, &block)
31
35
  end
32
36
  end
33
37
  else
@@ -1,6 +1,5 @@
1
1
  class Cyrax::Resource < Cyrax::Base
2
2
  include Cyrax::Extensions::HasResource
3
- include Cyrax::Extensions::HasRepository
4
3
  include Cyrax::Extensions::HasService
5
4
  include Cyrax::Extensions::HasDecorator
6
5
  include Cyrax::Extensions::HasSerializer
@@ -62,7 +62,12 @@ class Cyrax::Response
62
62
  end
63
63
 
64
64
  def method_missing(method, *args, &block)
65
- super unless assignments.has_key?(method)
66
- assignments[method]
65
+ if method.to_s == resource_name
66
+ result
67
+ elsif assignments.has_key?(method)
68
+ assignments[method]
69
+ else
70
+ super
71
+ end
67
72
  end
68
73
  end
@@ -1,7 +1,7 @@
1
1
  class Cyrax::Serializer < Cyrax::Wrapper
2
2
  def serialize
3
3
  options[:serializer] = self
4
-
4
+
5
5
  if block = self.class.total_count_block
6
6
  serialize_wrapped(options, &block)
7
7
  else
@@ -68,13 +68,14 @@ module Cyrax::Serializers
68
68
  value = resource.send(attribute)
69
69
  result[attribute] = scope.serialize(value, options)
70
70
  end
71
- @namespace_attrs.map do |attribute, scope|
72
- result[attribute] = scope.serialize(resource, options)
73
- end
74
71
  @assigned_attrs.map do |attribute, scope|
75
- value = options[:assignments][attribute]
72
+ assignments = options[:assignments] || {}
73
+ value = assignments[attribute]
76
74
  result[attribute] = scope.serialize(value, options)
77
75
  end
76
+ @namespace_attrs.map do |attribute, scope|
77
+ result[attribute] = scope.serialize(resource, options)
78
+ end
78
79
  @attrs.map do |attribute, options|
79
80
  result[attribute] = resource.send(attribute)
80
81
  end
data/lib/cyrax/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Cyrax
2
- VERSION = "0.7.7"
2
+ VERSION = "0.9.0"
3
3
  end
data/lib/cyrax.rb CHANGED
@@ -6,7 +6,6 @@ require "cyrax/extensions/has_response.rb"
6
6
  require "cyrax/extensions/has_service.rb"
7
7
  require "cyrax/extensions/has_decorator.rb"
8
8
  require "cyrax/extensions/has_serializer.rb"
9
- require "cyrax/extensions/has_repository.rb"
10
9
  require "cyrax/presenters/base_collection.rb"
11
10
  require "cyrax/presenters/decorated_collection.rb"
12
11
  require "cyrax/serializers/scope.rb"
@@ -18,10 +17,10 @@ require "cyrax/presenter.rb"
18
17
  require "cyrax/response.rb"
19
18
  require "cyrax/decorator.rb"
20
19
  require "cyrax/serializer.rb"
21
- require "cyrax/repository.rb"
22
20
 
23
21
  module Cyrax
24
22
  @@strong_parameters = true
23
+ @@automatically_set_invalid_status = true
25
24
 
26
25
  def self.strong_parameters
27
26
  @@strong_parameters
@@ -30,4 +29,12 @@ module Cyrax
30
29
  def self.strong_parameters=(value)
31
30
  @@strong_parameters = value
32
31
  end
32
+
33
+ def self.automatically_set_invalid_status
34
+ @@automatically_set_invalid_status
35
+ end
36
+
37
+ def self.automatically_set_invalid_status=(value)
38
+ @@automatically_set_invalid_status = value
39
+ end
33
40
  end
@@ -20,32 +20,32 @@ module Cyrax
20
20
  subject { BaseWithDecorator.new }
21
21
 
22
22
  describe 'class attributes' do
23
- its(:class) { should respond_to(:_decorator_class) }
23
+ its(:class) { should respond_to(:decorator_class_name) }
24
24
  end
25
25
 
26
26
  describe 'class methods' do
27
27
  describe '#decorator' do
28
- before { subject.class.decorator(Foo) }
28
+ before { subject.class.decorator(:foo) }
29
29
 
30
- its(:decorator_class) { should eq(Foo) }
30
+ its(:decorator_class_name) { 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(Foo) }
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(Foo) }
43
- its(:decorable?) { should be true }
42
+ before { subject.class.decorator(:foo) }
43
+ its(:decorable?) { should be_true }
44
44
  end
45
45
 
46
46
  context 'when `decorator_class_name` empty' do
47
47
  before { subject.class.decorator(nil) }
48
- its(:decorable?) { should be false }
48
+ its(:decorable?) { should be_false }
49
49
  end
50
50
  end
51
51
  end
@@ -18,17 +18,16 @@ module Cyrax
18
18
  subject { BaseWithResource.new }
19
19
 
20
20
  describe 'class attributes' do
21
- its(:class) { should respond_to(:_resource_name) }
22
- its(:class) { should respond_to(:_collection_name) }
23
- its(:class) { should respond_to(:_resource_class) }
21
+ its(:class) { should respond_to(:resource_name) }
22
+ its(:class) { should respond_to(:resource_class_name) }
24
23
  end
25
24
 
26
25
  describe 'class methods' do
27
26
  describe '#resource' do
28
- before { subject.class.resource(:foo, class: Bar, name:'bazz') }
27
+ before { subject.class.resource(:foo, class_name:'bar', name:'bazz') }
29
28
 
30
29
  its(:resource_name) { should eq('foo') }
31
- its(:resource_class) { should eq(Bar) }
30
+ its(:resource_class_name) { should eq('bar') }
32
31
  end
33
32
  end
34
33
 
@@ -46,7 +45,7 @@ module Cyrax
46
45
 
47
46
  describe '#resource_class' do
48
47
  context 'when `class_name` option is supplied' do
49
- before { subject.class.resource(:foo, class: Bar) }
48
+ before { subject.class.resource(:foo, class_name:'Bar') }
50
49
  its(:resource_class) { should eq(Bar) }
51
50
  end
52
51
 
@@ -56,6 +55,11 @@ module Cyrax
56
55
  end
57
56
  end
58
57
 
58
+ describe '#resource_scope' do
59
+ before { subject.stub(:resource_class).and_return(Foo) }
60
+ its(:resource_scope) { should eq(Foo) }
61
+ end
62
+
59
63
  describe '#resource_attributes' do
60
64
  let(:dirty_resource_attributes) { double }
61
65
  before { subject.stub(:dirty_resource_attributes).and_return(dirty_resource_attributes)}
@@ -84,6 +88,11 @@ module Cyrax
84
88
  end
85
89
  end
86
90
  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
87
96
 
88
97
  describe '#filter_attributes' do
89
98
  it 'should return supplied attributes by default' do
@@ -22,14 +22,14 @@ module Cyrax
22
22
  describe '#add_error' do
23
23
  it 'should add error' do
24
24
  subject.add_error(:foo, 'bar')
25
- subject.instance_variable_get(:@_errors).has_key?(:foo).should be true
25
+ subject.instance_variable_get(:@_errors).has_key?(:foo).should be_true
26
26
  end
27
27
  end
28
28
 
29
29
  describe '#add_error_unless' do
30
30
  it 'should add error when condition false' do
31
31
  subject.add_error_unless(:foo, 'bar', 1==0)
32
- subject.instance_variable_get(:@_errors).has_key?(:foo).should be true
32
+ subject.instance_variable_get(:@_errors).has_key?(:foo).should be_true
33
33
  end
34
34
 
35
35
  it 'should not add error when condition true' do
@@ -16,5 +16,48 @@ 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
19
62
  end
20
63
  end
@@ -10,7 +10,11 @@ module Cyrax
10
10
  it{ should respond_to(:params) }
11
11
  it{ should respond_to(:resource_name) }
12
12
  it{ should respond_to(:resource_class) }
13
+ it{ should respond_to(:resource_scope) }
13
14
  it{ should respond_to(:resource_attributes) }
15
+ it{ should respond_to(:build_resource) }
16
+ it{ should respond_to(:build_collection) }
17
+ it{ should respond_to(:find_resource) }
14
18
  it{ should respond_to(:assign_resource) }
15
19
  it{ should respond_to(:respond_with) }
16
20
  it{ should respond_to(:set_message) }
@@ -21,19 +25,17 @@ module Cyrax
21
25
  end
22
26
 
23
27
  subject { Cyrax::Resource.new }
24
- let(:repository) { double }
25
28
  let(:resource) { double.as_null_object }
26
29
  let(:collection) { [double] }
27
30
  before do
28
31
  subject.stub(:params).and_return({id:123})
29
- subject.stub(:repository).and_return(repository)
30
- repository.stub(:find).and_return(resource)
32
+ subject.stub(:find_resource).and_return(resource)
31
33
  subject.class.send :resource, :foo
32
34
  end
33
35
 
34
36
  describe '#read_all' do
35
37
  it 'responds with decorated collection' do
36
- repository.should_receive(:find_all).and_return(collection)
38
+ subject.should_receive(:build_collection).and_return(collection)
37
39
  subject.should_receive(:respond_with).with(collection, name: 'foos', present: :collection)
38
40
  subject.read_all
39
41
  end
@@ -41,7 +43,7 @@ module Cyrax
41
43
 
42
44
  describe '#build' do
43
45
  it 'responds with resource' do
44
- repository.should_receive(:build).with(nil).and_return(resource)
46
+ subject.should_receive(:build_resource).with(nil).and_return(resource)
45
47
  subject.should_receive(:respond_with).with(resource)
46
48
  subject.build
47
49
  end
@@ -49,7 +51,7 @@ module Cyrax
49
51
 
50
52
  describe '#edit' do
51
53
  it 'responds with resource' do
52
- repository.should_receive(:find)
54
+ subject.should_receive(:find_resource)
53
55
  subject.should_receive(:respond_with).with(resource)
54
56
  subject.edit
55
57
  end
@@ -57,34 +59,36 @@ module Cyrax
57
59
 
58
60
  describe '#read' do
59
61
  it 'responds with resource' do
60
- repository.should_receive(:find)
62
+ subject.should_receive(:find_resource)
61
63
  subject.should_receive(:respond_with).with(resource)
62
64
  subject.read
63
65
  end
64
66
  end
65
67
 
66
68
  describe '#destroy' do
67
- it 'destroys resource and responds with resource' do
68
- repository.should_receive(:find)
69
- repository.should_receive(:delete)
69
+ it 'responds with resource' do
70
+ subject.should_receive(:find_resource)
70
71
  subject.should_receive(:respond_with).with(resource)
71
72
  subject.destroy
72
73
  end
74
+
75
+ it 'destroys resource' do
76
+ resource.should_receive(:destroy)
77
+ subject.destroy
78
+ end
73
79
  end
74
80
 
75
81
  describe '#create' do
76
82
  let(:params) { {foo: 'bar'} }
77
- before { repository.stub(:build).and_return(resource) }
83
+ before { subject.stub(:build_resource).and_return(resource) }
78
84
  it 'responds with resource' do
79
- repository.should_receive(:save).with(resource)
80
- repository.should_receive(:build).with(nil)
81
- subject.should_receive(:set_resource_attributes).with(resource, params)
85
+ subject.should_receive(:build_resource).with(nil, params)
82
86
  subject.should_receive(:respond_with).with(resource)
83
87
  subject.create(params)
84
88
  end
85
89
 
86
90
  context 'when resource successfully saved' do
87
- before { repository.stub(:save).and_return(true) }
91
+ before { resource.stub(:save).and_return(true) }
88
92
 
89
93
  it 'sets message' do
90
94
  subject.should_receive(:set_message).with(:created)
@@ -93,28 +97,31 @@ module Cyrax
93
97
  end
94
98
 
95
99
  context 'when resource could not be saved' do
96
- before { repository.stub(:save).and_return(false) }
100
+ before { resource.stub(:save).and_return(false) }
97
101
 
98
102
  it 'does not set message' do
99
103
  subject.should_not_receive(:set_message).with(:created)
100
104
  subject.create(params)
101
105
  end
106
+
107
+ it "sets 422 status" do
108
+ subject.should_receive(:set_status).with(422)
109
+ subject.create(params)
110
+ end
102
111
  end
103
112
  end
104
113
 
105
114
  describe '#update' do
106
115
  let(:params) { {foo: 'bar'} }
107
- before { repository.stub(:build).and_return(resource) }
116
+ before { subject.stub(:build_resource).and_return(resource) }
108
117
  it 'responds with resource' do
109
- repository.should_receive(:build).with(123)
110
- repository.should_receive(:save).with(resource)
111
- subject.should_receive(:set_resource_attributes).with(resource, params)
118
+ subject.should_receive(:build_resource).with(123, params)
112
119
  subject.should_receive(:respond_with).with(resource)
113
120
  subject.update(params)
114
121
  end
115
122
 
116
123
  context 'when resource successfully saved' do
117
- before { repository.stub(:save).and_return(true) }
124
+ before { resource.stub(:save).and_return(true) }
118
125
 
119
126
  it 'sets message' do
120
127
  subject.should_receive(:set_message).with(:updated)
@@ -123,11 +130,16 @@ module Cyrax
123
130
  end
124
131
 
125
132
  context 'when resource could not be saved' do
126
- before { repository.stub(:save).and_return(false) }
133
+ before { resource.stub(:save).and_return(false) }
127
134
 
128
135
  it 'does not set message' do
129
136
  subject.should_not_receive(:set_message).with(:created)
130
- subject.create(params)
137
+ subject.update(params)
138
+ end
139
+
140
+ it "sets 422 status" do
141
+ subject.should_receive(:set_status).with(422)
142
+ subject.update(params)
131
143
  end
132
144
  end
133
145
  end
@@ -21,24 +21,24 @@ module Cyrax
21
21
  describe '#success?' do
22
22
  context 'when there are no errors' do
23
23
  before { subject.with_errors({}) }
24
- its(:success?) { should be true }
24
+ its(:success?) { should be_true }
25
25
  end
26
26
 
27
27
  context 'when there are errors' do
28
28
  before { subject.with_errors({foo: 'some', bar: 'errors'}) }
29
- its(:success?) { should be false }
29
+ its(:success?) { should be_false }
30
30
  end
31
31
  end
32
32
 
33
33
  describe '#failure?' do
34
34
  context 'when there are no errors' do
35
35
  before { subject.with_errors({}) }
36
- its(:failure?) { should be false }
36
+ its(:failure?) { should be_false }
37
37
  end
38
38
 
39
39
  context 'when there are errors' do
40
40
  before { subject.with_errors(['some', 'errors']) }
41
- its(:failure?) { should be true }
41
+ its(:failure?) { should be_true }
42
42
  end
43
43
  end
44
44
 
@@ -78,13 +78,13 @@ module Cyrax
78
78
  describe '#has_error?' do
79
79
  context 'when there are no errors' do
80
80
  before { subject.with_errors({}) }
81
- specify { subject.has_error?(:foo).should be false }
81
+ specify { subject.has_error?(:foo).should be_false }
82
82
  end
83
83
 
84
84
  context 'when there are errors' do
85
85
  before { subject.with_errors({foo: 'some', bar: 'errors'}) }
86
- specify { subject.has_error?(:foo).should be true }
87
- specify { subject.has_error?(:foo1).should be false }
86
+ specify { subject.has_error?(:foo).should be_true }
87
+ specify { subject.has_error?(:foo1).should be_false }
88
88
  end
89
89
  end
90
90
 
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cyrax
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.7
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Droidlabs
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-23 00:00:00.000000000 Z
11
+ date: 2023-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: activesupport
14
+ name: active_model_serializers
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: activemodel
28
+ name: activemodel-serializers-xml
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -38,6 +38,34 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activemodel
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.0'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: has_active_logger
43
71
  requirement: !ruby/object:Gem::Requirement
@@ -70,16 +98,16 @@ dependencies:
70
98
  name: sqlite3
71
99
  requirement: !ruby/object:Gem::Requirement
72
100
  requirements:
73
- - - ">="
101
+ - - "~>"
74
102
  - !ruby/object:Gem::Version
75
- version: '0'
103
+ version: 1.5.4
76
104
  type: :development
77
105
  prerelease: false
78
106
  version_requirements: !ruby/object:Gem::Requirement
79
107
  requirements:
80
- - - ">="
108
+ - - "~>"
81
109
  - !ruby/object:Gem::Version
82
- version: '0'
110
+ version: 1.5.4
83
111
  - !ruby/object:Gem::Dependency
84
112
  name: rspec
85
113
  requirement: !ruby/object:Gem::Requirement
@@ -95,7 +123,7 @@ dependencies:
95
123
  - !ruby/object:Gem::Version
96
124
  version: 2.99.0
97
125
  description: Small library for adding service layer to Rails projects
98
- email:
126
+ email:
99
127
  executables: []
100
128
  extensions: []
101
129
  extra_rdoc_files: []
@@ -107,7 +135,6 @@ files:
107
135
  - lib/cyrax/base.rb
108
136
  - lib/cyrax/decorator.rb
109
137
  - lib/cyrax/extensions/has_decorator.rb
110
- - lib/cyrax/extensions/has_repository.rb
111
138
  - lib/cyrax/extensions/has_resource.rb
112
139
  - lib/cyrax/extensions/has_response.rb
113
140
  - lib/cyrax/extensions/has_serializer.rb
@@ -116,7 +143,6 @@ files:
116
143
  - lib/cyrax/presenter.rb
117
144
  - lib/cyrax/presenters/base_collection.rb
118
145
  - lib/cyrax/presenters/decorated_collection.rb
119
- - lib/cyrax/repository.rb
120
146
  - lib/cyrax/resource.rb
121
147
  - lib/cyrax/response.rb
122
148
  - lib/cyrax/serializer.rb
@@ -126,20 +152,18 @@ files:
126
152
  - spec/cyrax/base_spec.rb
127
153
  - spec/cyrax/decorator_spec.rb
128
154
  - spec/cyrax/extensions/has_decorator_spec.rb
129
- - spec/cyrax/extensions/has_repository_spec.rb
130
155
  - spec/cyrax/extensions/has_resource_spec.rb
131
156
  - spec/cyrax/extensions/has_response_spec.rb
132
157
  - spec/cyrax/extensions/has_service_spec.rb
133
- - spec/cyrax/repository_spec.rb
134
158
  - spec/cyrax/resource_spec.rb
135
159
  - spec/cyrax/response_spec.rb
136
160
  - spec/cyrax/serializer_spec.rb
137
161
  - spec/spec_helper.rb
138
- homepage:
162
+ homepage:
139
163
  licenses:
140
164
  - MIT
141
165
  metadata: {}
142
- post_install_message:
166
+ post_install_message:
143
167
  rdoc_options: []
144
168
  require_paths:
145
169
  - lib
@@ -154,21 +178,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
178
  - !ruby/object:Gem::Version
155
179
  version: '0'
156
180
  requirements: []
157
- rubyforge_project:
158
- rubygems_version: 2.4.3
159
- signing_key:
181
+ rubygems_version: 3.0.9
182
+ signing_key:
160
183
  specification_version: 4
161
184
  summary: Small library for adding service layer to Rails projects
162
185
  test_files:
163
- - spec/cyrax/base_spec.rb
164
- - spec/cyrax/decorator_spec.rb
186
+ - spec/spec_helper.rb
187
+ - spec/cyrax/resource_spec.rb
188
+ - spec/cyrax/extensions/has_response_spec.rb
165
189
  - spec/cyrax/extensions/has_decorator_spec.rb
166
- - spec/cyrax/extensions/has_repository_spec.rb
167
190
  - spec/cyrax/extensions/has_resource_spec.rb
168
- - spec/cyrax/extensions/has_response_spec.rb
169
191
  - spec/cyrax/extensions/has_service_spec.rb
170
- - spec/cyrax/repository_spec.rb
171
- - spec/cyrax/resource_spec.rb
172
192
  - spec/cyrax/response_spec.rb
193
+ - spec/cyrax/decorator_spec.rb
173
194
  - spec/cyrax/serializer_spec.rb
174
- - spec/spec_helper.rb
195
+ - spec/cyrax/base_spec.rb
@@ -1,48 +0,0 @@
1
- module Cyrax::Extensions
2
- module HasRepository
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- class_attribute :_repository_class
7
- class_attribute :_repository_options
8
- end
9
-
10
- def repository_class
11
- options[:repository] || self.class._repository_class || Cyrax::Repository
12
- end
13
-
14
- def repository
15
- options = (self.class._repository_options || {}).merge(
16
- as: accessor, resource_class: resource_class, params: params
17
- )
18
- repository_class.new(options)
19
- end
20
-
21
- module ClassMethods
22
- def inherited(subclass)
23
- subclass._repository_options = self._repository_options.try(:clone)
24
- end
25
-
26
- def repository(name = nil, &block)
27
- if name.is_a?(Symbol)
28
- klass, finder_name = nil, name
29
- elsif name.is_a?(String)
30
- ActiveSupport::Deprecation.warn "sending String in #decorator method is deprecated. send Class instead"
31
- klass, finder_name = name.constantize, nil
32
- elsif name.present?
33
- klass, finder_name = name, nil
34
- end
35
-
36
- if klass.present?
37
- self._repository_class = klass
38
- end
39
- if block_given?
40
- self._repository_options = self._repository_options.try(:clone)
41
- self._repository_options ||= {}
42
- self._repository_options[:finders] ||= {}
43
- self._repository_options[:finders][finder_name || :scope] = block
44
- end
45
- end
46
- end
47
- end
48
- end
@@ -1,113 +0,0 @@
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 :finders
8
-
9
- def initialize(options = {})
10
- @options = options
11
- @accessor = options[:as]
12
- @params = options[:params]
13
- @resource_class = options[:resource_class]
14
- @finders = options[:finders] || {}
15
- end
16
-
17
- def finder(name, *attrs)
18
- block = finders[name]
19
- instance_exec(*attrs, &block)
20
- end
21
-
22
- def finder?(name)
23
- finders.has_key?(name)
24
- end
25
-
26
- def finder_or_run(name, *attrs)
27
- finder?(name) ? finder(name, *attrs) : send("#{name}!", *attrs)
28
- end
29
-
30
- # Returns the resource class - e.g. Product by default.
31
- # If you want your repository to scope with something interesting,
32
- # you should override this in your repository by defining the method and returning your own scope
33
- #
34
- # @example Overriding scope
35
- # class Products::Repository < Cyrax::Repository
36
- # def scope
37
- # accessor.products
38
- # end
39
- # end
40
- def scope
41
- finder_or_run(:scope)
42
- end
43
- def scope!
44
- resource_class
45
- end
46
-
47
- # Instantiates the resource
48
- # @param id [int] ID or nil if you want a new object
49
- # @param attributes [hash] Attributes you want to add to the resource
50
- # @return [object] The object
51
- def build(id, attributes = {})
52
- finder_or_run(:build, id, attributes)
53
- end
54
- def build!(id, attributes = {})
55
- if id.present?
56
- resource = find(id)
57
- resource.attributes = attributes
58
- resource
59
- else
60
- scope.new(default_attributes.merge(attributes))
61
- end
62
- end
63
-
64
- # Finds and returns a multiple items within the scope from the DB
65
- # @return [Array] Array of objects
66
- def find_all
67
- finder_or_run(:find_all)
68
- end
69
- def find_all!
70
- defined?(ActiveRecord) && scope.is_a?(ActiveRecord::Relation) ? scope.load : scope.all
71
- end
72
-
73
- # Finds and returns a single item from the DB
74
- # @param id [int] ID of item
75
- # @return [object] The object
76
- def find(id)
77
- finder_or_run(:find, id)
78
- end
79
- def find!(id)
80
- scope.find(id)
81
- end
82
-
83
- # Saves a resource
84
- # @param resource [object] The resource to save
85
- def save(resource)
86
- finder_or_run(:save, resource)
87
- end
88
- def save!(resource)
89
- resource.save
90
- end
91
-
92
- # Removes a resource
93
- # Calls destroy method on resource
94
- # @param resource [object] The resource to destroy
95
- def delete(resource)
96
- finder_or_run(:delete, resource)
97
- end
98
- def delete!(resource)
99
- resource.destroy
100
- end
101
-
102
- def default_attributes
103
- finder_or_run(:default_attributes)
104
- end
105
- def default_attributes!
106
- {}
107
- end
108
-
109
- def method_missing(method, *args, &block)
110
- return super unless finder?(method)
111
- finder(method, *args)
112
- end
113
- end
@@ -1,28 +0,0 @@
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
@@ -1,72 +0,0 @@
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