azeroth 0.8.2 → 0.10.1

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
2
  SHA256:
3
- metadata.gz: b37d53edb3f9b83aca0a7b121040c8db535da8b40d1bbc863c4d0b368dabe65d
4
- data.tar.gz: 567d011f2f370e24d4b182182cfed7d08e46e344e533f6caccc1529c1c318643
3
+ metadata.gz: bcc284d1b166fec28f03e31cd42642ad09a86c85a81718ba401531443b1bbc08
4
+ data.tar.gz: 335851aa5d9a160cf387971e904248c2f89041594ccdaec57fa9ab130624558f
5
5
  SHA512:
6
- metadata.gz: 8c89d250bf8825965909dcc57aac1adb333cc06995cc27e381a78a442fd3c0ce187d33f6b39b2f3a002eeb97e9ca5462a44d2f81ca957d3aa8810bd1441b8081
7
- data.tar.gz: 0eb7564aa351c821bf88cf25d7ca3991eb239089b492dc31587526b437067f9436fdb175c86a7ca937fc457d76fb546e4c8cc5159236cc88145ed06ac215e3f6
6
+ metadata.gz: 7ef7afcbd3282d181339fa6f154d1b4dcb6c6bad00f7c4e33e5c0b912b55eecc7de9876e44d2d54e7709a006a7cef487ee6c057dc0645bc0e336ff2b70629fdf
7
+ data.tar.gz: d37ba6ffdfe83b55fd51f103fd9ba3f35a3edf5eb0121c5aab424da29ffcce3e7850d52acdb4c41097c773d2f5b56692dc5f0e6c751ebce1651153bde42f2e1d
data/.circleci/config.yml CHANGED
@@ -22,7 +22,7 @@ workflows:
22
22
  jobs:
23
23
  test:
24
24
  docker:
25
- - image: darthjee/circleci_rails_gems:0.8.0
25
+ - image: darthjee/circleci_rails_gems:1.1.0
26
26
  environment:
27
27
  PROJECT: azeroth
28
28
  steps:
@@ -41,7 +41,7 @@ jobs:
41
41
  command: cc-test-reporter after-build --exit-code $?
42
42
  checks:
43
43
  docker:
44
- - image: darthjee/circleci_rails_gems:0.8.0
44
+ - image: darthjee/circleci_rails_gems:1.1.0
45
45
  environment:
46
46
  PROJECT: azeroth
47
47
  steps:
@@ -66,7 +66,7 @@ jobs:
66
66
  command: check_specs
67
67
  build-and-release:
68
68
  docker:
69
- - image: darthjee/circleci_rails_gems:0.8.0
69
+ - image: darthjee/circleci_rails_gems:1.1.0
70
70
  environment:
71
71
  PROJECT: azeroth
72
72
  steps:
data/.gitignore CHANGED
@@ -11,3 +11,4 @@ rubycritic/
11
11
  spec/dummy/log/*
12
12
  spec/dummy/tmp/*
13
13
  spec/dummy/db/*.sqlite3
14
+ spec/dummy/db/*.sqlite3-journal
data/Dockerfile CHANGED
@@ -1,12 +1,14 @@
1
- FROM darthjee/rails_gems:0.8.0 as base
2
- FROM darthjee/scripts:0.1.8 as scripts
1
+ FROM darthjee/scripts:0.3.1 as scripts
2
+
3
+ FROM darthjee/rails_gems:1.1.0 as base
4
+
5
+ COPY --chown=app:app ./ /home/app/app/
3
6
 
4
7
  ######################################
5
8
 
6
9
  FROM base as builder
7
10
 
8
- COPY --chown=app ./ /home/app/app/
9
- COPY --chown=app:app --from=scripts /home/scripts/builder/bundle_builder.sh /usr/local/sbin/
11
+ COPY --chown=app:app --from=scripts /home/scripts/builder/bundle_builder.sh /usr/local/sbin/bundle_builder.sh
10
12
 
11
13
  ENV HOME_DIR /home/app
12
14
  RUN bundle_builder.sh
@@ -14,11 +16,6 @@ RUN bundle_builder.sh
14
16
  #######################
15
17
  #FINAL IMAGE
16
18
  FROM base
17
- RUN mkdir lib/azeroth -p
18
19
 
19
20
  COPY --chown=app:app --from=builder /home/app/bundle/ /usr/local/bundle/
20
-
21
- COPY --chown=app ./*.gemspec ./Gemfile /home/app/app/
22
- COPY --chown=app ./lib/azeroth/version.rb /home/app/app/lib/azeroth/
23
-
24
21
  RUN bundle install
data/README.md CHANGED
@@ -11,7 +11,7 @@ Azeroth
11
11
 
12
12
  Yard Documentation
13
13
  -------------------
14
- [https://www.rubydoc.info/gems/azeroth/0.8.2](https://www.rubydoc.info/gems/azeroth/0.8.2)
14
+ [https://www.rubydoc.info/gems/azeroth/0.10.1](https://www.rubydoc.info/gems/azeroth/0.10.1)
15
15
 
16
16
  Azeroth has been designed making the coding of controllers easier
17
17
  as routes in controllers are usually copy, paste and replace of same
@@ -61,6 +61,7 @@ It accepts options
61
61
  - before_save: Method/Proc to be ran before saving the resource on create or update
62
62
  - after_save: Method/Proc to be ran after saving the resource on create or update
63
63
  - build_with: Method/Block to be ran when building the reource on create
64
+ - update_with: Method/Block to be ran when updating the reource on update
64
65
  - paginated: Flag when pagination should be applied
65
66
  - per_page: Number of items returned when pagination is active
66
67
 
@@ -171,6 +172,35 @@ defining which and how fields will be exposed
171
172
  end
172
173
  ```
173
174
 
175
+ ```ruby
176
+ class PaginatedDocumentsController < ApplicationController
177
+ include Azeroth::Resourceable
178
+
179
+ resource_for :document, only: 'index', paginated: true
180
+ end
181
+
182
+ 30.times { create(:document) }
183
+
184
+ get '/paginated_documents.json'
185
+
186
+ # returns Array with 20 first documents
187
+ # returns in the headers pagination headers
188
+ {
189
+ 'pages' => 2,
190
+ 'per_page' => 20,
191
+ 'page' => 1
192
+ }
193
+
194
+ get '/paginated_documents.json?page=2'
195
+
196
+ # returns Array with 10 next documents
197
+ # returns in the headers pagination headers
198
+ {
199
+ 'pages' => 2,
200
+ 'per_page' => 20,
201
+ 'page' => 2
202
+ }
203
+ ```
174
204
  Exposing is done through the class method
175
205
  [expose](https://www.rubydoc.info/gems/azeroth/Azeroth/Decorator#expose-class_method)
176
206
  which accepts several options:
data/azeroth.gemspec CHANGED
@@ -20,33 +20,35 @@ Gem::Specification.new do |gem|
20
20
 
21
21
  gem.add_runtime_dependency 'activesupport', '~> 5.2.x'
22
22
  gem.add_runtime_dependency 'darthjee-active_ext', '>= 1.3.2'
23
- gem.add_runtime_dependency 'jace', '>= 0.0.3'
23
+ gem.add_runtime_dependency 'jace', '>= 0.1.1'
24
24
  gem.add_runtime_dependency 'sinclair', '>= 1.6.7'
25
25
 
26
- gem.add_development_dependency 'actionpack', '~> 5.2.x'
27
- gem.add_development_dependency 'activerecord', '~> 5.2.x'
28
- gem.add_development_dependency 'bundler', '1.16.1'
29
- gem.add_development_dependency 'factory_bot', '5.2.0'
30
- gem.add_development_dependency 'nokogiri', '1.12.5'
31
- gem.add_development_dependency 'pry', '0.12.2'
32
- gem.add_development_dependency 'pry-nav', '0.3.0'
33
- gem.add_development_dependency 'rails', '~> 5.2.x'
34
- gem.add_development_dependency 'rails-controller-testing', '1.0.4'
35
- gem.add_development_dependency 'rake', '13.0.3'
26
+ gem.add_development_dependency 'actionpack', '5.2.8.1'
27
+ gem.add_development_dependency 'activerecord', '5.2.8.1'
28
+ gem.add_development_dependency 'bundler', '~> 2.3.14'
29
+ gem.add_development_dependency 'factory_bot', '6.2.1'
30
+ gem.add_development_dependency 'minitest', '5.16.2'
31
+ gem.add_development_dependency 'nokogiri', '1.13.6'
32
+ gem.add_development_dependency 'pry', '0.14.1'
33
+ gem.add_development_dependency 'pry-nav', '1.0.0'
34
+ gem.add_development_dependency 'rails', '5.2.8.1'
35
+ gem.add_development_dependency 'rails-controller-testing', '1.0.5'
36
+ gem.add_development_dependency 'rake', '13.0.6'
36
37
  gem.add_development_dependency 'reek', '6.0.3'
37
- gem.add_development_dependency 'rspec', '3.9.0'
38
+ gem.add_development_dependency 'rspec', '3.11.0'
38
39
  gem.add_development_dependency 'rspec-collection_matchers', '1.2.0'
39
- gem.add_development_dependency 'rspec-core', '3.9.3'
40
- gem.add_development_dependency 'rspec-expectations', '3.9.4'
41
- gem.add_development_dependency 'rspec-mocks', '3.9.1'
42
- gem.add_development_dependency 'rspec-rails', '3.9.0'
43
- gem.add_development_dependency 'rspec-support', '3.9.4'
40
+ gem.add_development_dependency 'rspec-core', '3.11.0'
41
+ gem.add_development_dependency 'rspec-expectations', '3.11.0'
42
+ gem.add_development_dependency 'rspec-mocks', '3.11.1'
43
+ gem.add_development_dependency 'rspec-rails', '5.1.2'
44
+ gem.add_development_dependency 'rspec-support', '3.11.0'
44
45
  gem.add_development_dependency 'rubocop', '0.80.1'
45
46
  gem.add_development_dependency 'rubocop-rspec', '1.38.1'
46
- gem.add_development_dependency 'rubycritic', '4.6.1'
47
+ gem.add_development_dependency 'rubycritic', '4.7.0'
47
48
  gem.add_development_dependency 'shoulda-matchers', '4.3.0'
48
- gem.add_development_dependency 'simplecov', '0.17.1'
49
+ gem.add_development_dependency 'simplecov', '0.21.2'
49
50
  gem.add_development_dependency 'sqlite3', '1.4.2'
50
- gem.add_development_dependency 'yard', '0.9.26'
51
+ gem.add_development_dependency 'tzinfo-data', '~> 1.2022.1'
52
+ gem.add_development_dependency 'yard', '0.9.27'
51
53
  gem.add_development_dependency 'yardstick', '0.9.9'
52
54
  end
data/config/yardstick.yml CHANGED
@@ -31,6 +31,7 @@ rules:
31
31
  - Azeroth::Exception::InvalidOptions#initialize
32
32
  - Azeroth::Model#initialize
33
33
  - Azeroth::Options#initialize
34
+ - Azeroth::ParamsBuilder#initialize
34
35
  - Azeroth::RequestHandler#initialize
35
36
  - Azeroth::ResourceBuilder#initialize
36
37
  - Azeroth::ResourceRouteBuilder#initialize
@@ -42,6 +42,21 @@ module Azeroth
42
42
  controller.instance_variable_set("@#{variable}", value)
43
43
  end
44
44
 
45
+ # Forces a controller to run a block
46
+ #
47
+ # When the block is a +Proc+ that is evaluated,
48
+ # when it is a +Symbol+ or +String+, a method is called
49
+ #
50
+ # @return [Object] whatever the block returns
51
+ def run(block)
52
+ case block
53
+ when Proc
54
+ controller.instance_eval(&block)
55
+ else
56
+ controller.send(block)
57
+ end
58
+ end
59
+
45
60
  private
46
61
 
47
62
  attr_reader :controller
@@ -21,6 +21,7 @@ module Azeroth
21
21
  before_save: nil,
22
22
  after_save: nil,
23
23
  build_with: nil,
24
+ update_with: nil,
24
25
  paginated: false,
25
26
  per_page: 20
26
27
  }.freeze
@@ -34,18 +35,13 @@ module Azeroth
34
35
  [only].flatten.map(&:to_sym) - [except].flatten.map(&:to_sym)
35
36
  end
36
37
 
37
- # Returns event dispatcher
38
+ # Returns the event registry
38
39
  #
39
- # Event dispatcher is responsible for
40
- # sending events such as +before_save+
41
- # to it's correct calling point
40
+ # Event registry is used to handle events within the request
42
41
  #
43
- # @return [Jace::Dispatcher]
44
- def event_dispatcher(event)
45
- Jace::Dispatcher.new(
46
- before: try("before_#{event}"),
47
- after: try("after_#{event}")
48
- )
42
+ # @return [Jace::Registry]
43
+ def event_registry
44
+ @event_registry ||= build_event_registry
49
45
  end
50
46
 
51
47
  alias paginated? paginated
@@ -110,6 +106,13 @@ module Azeroth
110
106
  #
111
107
  # @return [Symbol,Proc]
112
108
 
109
+ # @method update_with
110
+ # @api private
111
+ #
112
+ # Block or method name to be ran when updating the resource
113
+ #
114
+ # @return [Symbol,Proc]
115
+
113
116
  # @method paginated
114
117
  # @api private
115
118
  #
@@ -123,5 +126,22 @@ module Azeroth
123
126
  # Number of elements when pagination is active
124
127
  #
125
128
  # @return [Integer]
129
+
130
+ private
131
+
132
+ # private
133
+ #
134
+ # Builds the event registr
135
+ #
136
+ # The event registry is build using the before
137
+ # and after actions defined in optionsy
138
+ #
139
+ # @return [Jace::Registry]
140
+ def build_event_registry
141
+ Jace::Registry.new.tap do |registry|
142
+ registry.register(:save, :after, &after_save)
143
+ registry.register(:save, :before, &before_save)
144
+ end
145
+ end
126
146
  end
127
147
  end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Azeroth
4
+ # @api private
5
+ # @author Darthjee
6
+ #
7
+ # Class responsible for adding params handling methods to a controller
8
+ class ParamsBuilder
9
+ # @param model [Model] resource interface
10
+ # @param builder [Sinclair] methods builder
11
+ def initialize(model, builder)
12
+ @model = model
13
+ @builder = builder
14
+ end
15
+
16
+ # Append the params methods to be built
17
+ #
18
+ # @return [Array<Sinclair::MethodDefinition>]
19
+ def append
20
+ method_name = name
21
+ allowed_attributes = permitted_attributes.map(&:to_sym)
22
+
23
+ add_method("#{name}_id") { params.require(:id) }
24
+ add_method("#{name}_params") do
25
+ params.require(method_name)
26
+ .permit(*allowed_attributes)
27
+ end
28
+ end
29
+
30
+ attr_reader :model, :builder
31
+ # @method model
32
+ # @api private
33
+ # @private
34
+ #
35
+ # Resource interface
36
+ #
37
+ # @return [Model]
38
+
39
+ # @method builder
40
+ # @api private
41
+ # @private
42
+ #
43
+ # Methods builder
44
+ #
45
+ # @return [Sinclair]
46
+
47
+ delegate :add_method, to: :builder
48
+ # @method add_method
49
+ # @api private
50
+ # @private
51
+ #
52
+ # Appends a method
53
+ #
54
+ # @return [Array<Sinclair::MethodDefinition>]
55
+
56
+ delegate :name, :klass, to: :model
57
+ # @method name
58
+ # @api private
59
+ # @private
60
+ #
61
+ # Resource name
62
+ #
63
+ # @return [Symbol,String]
64
+
65
+ # @method klass
66
+ # @api private
67
+ # @private
68
+ #
69
+ # Controller to be changed
70
+ #
71
+ # @return [Array<Sinclair::MethodDefinition>]
72
+
73
+ # Returns all updatable attributes
74
+ #
75
+ # @return [Array<String>]
76
+ def permitted_attributes
77
+ @permitted_attributes ||= klass.attribute_names - ['id']
78
+ end
79
+ end
80
+ end
@@ -47,12 +47,7 @@ module Azeroth
47
47
  def build_resource
48
48
  return collection.build(attributes) unless build_with
49
49
 
50
- case build_with
51
- when Proc
52
- controller.instance_eval(&build_with)
53
- else
54
- controller.send(build_with)
55
- end
50
+ controller.run(build_with)
56
51
  end
57
52
 
58
53
  # @private
@@ -8,6 +8,8 @@ module Azeroth
8
8
  class Update < RequestHandler
9
9
  private
10
10
 
11
+ delegate :update_with, to: :options
12
+
11
13
  # @private
12
14
  #
13
15
  # Updates and return an instance of the model
@@ -17,20 +19,35 @@ module Azeroth
17
19
  #
18
20
  # @return [Object]
19
21
  def resource
20
- @resource ||= update_resource
22
+ @resource ||= perform_update
21
23
  end
22
24
 
23
- # build resource for update
25
+ # Update a resource saving it to the database
24
26
  #
25
- # @return [Object]
26
- def update_resource
27
- controller.send(model.name).tap do |entry|
27
+ # @return [Object] updated resource
28
+ def perform_update
29
+ @resource = controller.send(model.name)
30
+ resource.tap do
28
31
  trigger_event(:save) do
29
- entry.update(attributes)
32
+ update_and_save_resource
30
33
  end
31
34
  end
32
35
  end
33
36
 
37
+ # @private
38
+ #
39
+ # Update the resource
40
+ #
41
+ # This update happens by either by running update_with
42
+ # or directly updating the attributes in the object
43
+ #
44
+ # @return [Object] updated resource
45
+ def update_and_save_resource
46
+ return resource.update(attributes) unless update_with
47
+
48
+ controller.run(update_with)
49
+ end
50
+
34
51
  # @private
35
52
  #
36
53
  # Response status
@@ -119,8 +119,7 @@ module Azeroth
119
119
  #
120
120
  # @return [Object] Result of given block
121
121
  def trigger_event(event, &block)
122
- options.event_dispatcher(event)
123
- .dispatch(controller, &block)
122
+ options.event_registry.trigger(event, controller, &block)
124
123
  end
125
124
 
126
125
  # @private
@@ -71,7 +71,7 @@ module Azeroth
71
71
  #
72
72
  # @return [Array<Sinclair::MethodDefinition>]
73
73
 
74
- delegate :name, :klass, to: :model
74
+ delegate :name, to: :model
75
75
  # @method name
76
76
  # @api private
77
77
  # @private
@@ -80,14 +80,6 @@ module Azeroth
80
80
  #
81
81
  # @return [Symbol,String]
82
82
 
83
- # @method klass
84
- # @api private
85
- # @private
86
- #
87
- # Controller to be changed
88
- #
89
- # @return [Array<Sinclair::MethodDefinition>]
90
-
91
83
  # @api private
92
84
  # @private
93
85
  #
@@ -104,14 +96,7 @@ module Azeroth
104
96
  #
105
97
  # @return [Array<Sinclair::MethodDefinition>]
106
98
  def add_params
107
- add_method("#{name}_id", 'params.require(:id)')
108
- add_method(
109
- "#{name}_params",
110
- <<-CODE
111
- params.require(:#{name})
112
- .permit(:#{permitted_attributes.join(', :')})
113
- CODE
114
- )
99
+ ParamsBuilder.new(model, builder).append
115
100
  end
116
101
 
117
102
  # Add methods for resource fetching
@@ -135,13 +120,6 @@ module Azeroth
135
120
  clazz.public_send(:helper_method, model.name)
136
121
  clazz.public_send(:helper_method, model.plural)
137
122
  end
138
-
139
- # Returns all updatable attributes
140
- #
141
- # @return [Array<String>]
142
- def permitted_attributes
143
- @permitted_attributes ||= klass.attribute_names - ['id']
144
- end
145
123
  end
146
124
  end
147
125
  end
@@ -14,136 +14,7 @@ module Azeroth
14
14
  # @return (see Resourceable.resource_for)
15
15
  #
16
16
  # @see (see Resourceable.resource_for)
17
- #
18
- # @example Controller without delete
19
- # class DocumentsController < ApplicationController
20
- # include Azeroth::Resourceable
21
- #
22
- # resource_for :document, except: :delete
23
- # end
24
- #
25
- # @example Controller with only create, show and list
26
- # class DocumentsController < ApplicationController
27
- # include Azeroth::Resourceable
28
- #
29
- # resource_for :document, only: %w[create index show]
30
- # end
31
- #
32
- # @example complete example gmaes and publishers
33
- # class PublishersController < ApplicationController
34
- # include Azeroth::Resourceable
35
- # skip_before_action :verify_authenticity_token
36
- #
37
- # resource_for :publisher, only: %i[create index]
38
- # end
39
- #
40
- # class GamesController < ApplicationController
41
- # include Azeroth::Resourceable
42
- # skip_before_action :verify_authenticity_token
43
- #
44
- # resource_for :game, except: :delete
45
- #
46
- # private
47
- #
48
- # def games
49
- # publisher.games
50
- # end
51
- #
52
- # def publisher
53
- # @publisher ||= Publisher.find(publisher_id)
54
- # end
55
- #
56
- # def publisher_id
57
- # params.require(:publisher_id)
58
- # end
59
- # end
60
- #
61
- # ActiveRecord::Schema.define do
62
- # self.verbose = false
63
- #
64
- # create_table :publishers, force: true do |t|
65
- # t.string :name
66
- # end
67
- #
68
- # create_table :games, force: true do |t|
69
- # t.string :name
70
- # t.integer :publisher_id
71
- # end
72
- # end
73
- #
74
- # class Publisher < ActiveRecord::Base
75
- # has_many :games
76
- # end
77
- #
78
- # class Game < ActiveRecord::Base
79
- # belongs_to :publisher
80
- # end
81
- #
82
- # class Game::Decorator < Azeroth::Decorator
83
- # expose :id
84
- # expose :name
85
- # expose :publisher, decorator: NameDecorator
86
- # end
87
- #
88
- # @example requesting games and publishers
89
- # post "/publishers.json", params: {
90
- # publisher: {
91
- # name: 'Nintendo'
92
- # }
93
- # }
94
- #
95
- # publisher = JSON.parse(response.body)
96
- # # returns
97
- # # {
98
- # # 'id' => 11,
99
- # # 'name' => 'Nintendo'
100
- # # }
101
- #
102
- # publisher = Publisher.last
103
- # post "/publishers/#{publisher['id']}/games.json", params: {
104
- # game: {
105
- # name: 'Pokemon'
106
- # }
107
- # }
108
- #
109
- # game = Game.last
110
- #
111
- # JSON.parse(response.body)
112
- # # returns
113
- # # {
114
- # # id: game.id,
115
- # # name: 'Pokemon',
116
- # # publisher: {
117
- # # name: 'Nintendo'
118
- # # }
119
- # }
120
- #
121
- # @example Controller with before_save
122
- # class PokemonsController < ApplicationController
123
- # include Azeroth::Resourceable
124
- #
125
- # resource_for :pokemon,
126
- # only: %i[create update],
127
- # before_save: :set_favorite
128
- #
129
- # private
130
- #
131
- # def set_favorite
132
- # pokemon.favorite = true
133
- # end
134
- #
135
- # def pokemons
136
- # master.pokemons
137
- # end
138
- #
139
- # def master
140
- # @master ||= PokemonMaster.find(master_id)
141
- # end
142
- #
143
- # def master_id
144
- # params.require(:pokemon_master_id)
145
- # end
146
- # end
17
+ # @example (see Resourceable.resource_for)
147
18
  def resource_for(name, **options)
148
19
  Builder.new(
149
20
  self, name, Azeroth::Options.new(options)