cyrax 0.7.7 → 0.9.0

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 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