pragma-rails 1.2.4 → 2.0.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.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rspec +1 -2
  4. data/.rubocop.yml +9 -1
  5. data/Gemfile +6 -0
  6. data/README.md +80 -21
  7. data/lib/generators/pragma/resource_generator.rb +68 -0
  8. data/lib/generators/pragma/templates/resource/controller.rb.tt +6 -0
  9. data/lib/generators/pragma/templates/resource/resource/contract/base.rb.tt +10 -0
  10. data/lib/generators/pragma/templates/resource/resource/contract/create.rb.tt +10 -0
  11. data/lib/generators/pragma/templates/resource/resource/contract/update.rb.tt +10 -0
  12. data/lib/generators/pragma/templates/resource/resource/decorator/collection.rb.tt +15 -0
  13. data/lib/generators/pragma/templates/resource/resource/decorator/instance.rb.tt +11 -0
  14. data/lib/generators/pragma/templates/resource/resource/operation/create.rb.tt +10 -0
  15. data/lib/generators/pragma/templates/resource/resource/operation/destroy.rb.tt +10 -0
  16. data/lib/generators/pragma/templates/resource/resource/operation/index.rb.tt +10 -0
  17. data/lib/generators/pragma/templates/resource/resource/operation/show.rb.tt +10 -0
  18. data/lib/generators/pragma/templates/resource/resource/operation/update.rb.tt +10 -0
  19. data/lib/generators/pragma/templates/resource/resource/policy.rb.tt +29 -0
  20. data/lib/generators/pragma/templates/resource/spec.rb.tt +99 -0
  21. data/lib/pragma/rails.rb +3 -1
  22. data/lib/pragma/rails/controller.rb +21 -39
  23. data/lib/pragma/rails/resource_controller.rb +3 -2
  24. data/lib/pragma/rails/version.rb +2 -1
  25. data/pragma-rails.gemspec +10 -3
  26. metadata +103 -6
  27. data/lib/pragma/rails/hooks.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ef2c94828fb6e2b96aff4786860d5e31abc25bde
4
- data.tar.gz: aaef580bc6920a156cbc751066767aea6a05a4a1
3
+ metadata.gz: b813fe8cf53b4558b118cca550eb851dff77b9f4
4
+ data.tar.gz: 7e675468e6837c1a63b4e8c957bf701232446b56
5
5
  SHA512:
6
- metadata.gz: e23f4b1a3dc5bac1cc06d9ffa4319c3b3a1ba419547a37426357626ef6166513e87e21f28aab9665fe544fb933abd9da58a5575145a940186f0a9340898d2e07
7
- data.tar.gz: 6be0675127df08306c7cad8dbf75ea49ccbdd0eda49a643e3ed46810b2a5d022f4a983190dee328f68764f220b6d2d5f0bff3af70d3607f511d78f7ec2bf368f
6
+ metadata.gz: 5a2a1055ba16a3bd8a7feb6a67a03af1a140d6470aa814a62677c5ef8b77fc598486d16eb17da2d0e6f44624dc7740a9c4610148526285c74bdb80fc6fc8a1a8
7
+ data.tar.gz: 63dc8ac52215dab16588f3906ad9c0a9226a2ef481d7852fd82e640f0c9cba317e8888b9da62b28ccd56e3b0b6f12a7541f9d3b96d98966acabcebeb93c93955
data/.gitignore CHANGED
@@ -7,3 +7,6 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
  /spec/examples.txt
10
+ /spec/dummy/db/*.sqlite3
11
+ /spec/dummy/tmp
12
+ /spec/dummy/log/*.log
data/.rspec CHANGED
@@ -1,3 +1,2 @@
1
- --format documentation
2
1
  --color
3
- --require spec_helper
2
+ --require rails_helper
data/.rubocop.yml CHANGED
@@ -12,6 +12,7 @@ AllCops:
12
12
  - 'spec/spec_helper.rb'
13
13
  - 'spec/rails_helper.rb'
14
14
  - 'spec/support/**/*'
15
+ - 'spec/dummy/**/*'
15
16
  - 'config/**/*'
16
17
  - '**/Rakefile'
17
18
  - '**/Gemfile'
@@ -24,6 +25,10 @@ Style/BlockDelimiters:
24
25
  Exclude:
25
26
  - 'spec/**/*'
26
27
 
28
+ Style/FileName:
29
+ Exclude:
30
+ - 'pragma-rails.gemspec'
31
+
27
32
  Style/AlignParameters:
28
33
  EnforcedStyle: with_fixed_indentation
29
34
 
@@ -53,7 +58,7 @@ Style/BracesAroundHashParameters:
53
58
  EnforcedStyle: context_dependent
54
59
 
55
60
  Lint/EndAlignment:
56
- AlignWith: variable
61
+ EnforcedStyleAlignWith: variable
57
62
  AutoCorrect: true
58
63
 
59
64
  Style/AndOr:
@@ -86,6 +91,9 @@ Metrics/CyclomaticComplexity:
86
91
  Metrics/ClassLength:
87
92
  Enabled: false
88
93
 
94
+ Metrics/BlockLength:
95
+ Enabled: false
96
+
89
97
  RSpec/MessageExpectation:
90
98
  Enabled: false
91
99
 
data/Gemfile CHANGED
@@ -2,3 +2,9 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in pragma-rails.gemspec
4
4
  gemspec
5
+
6
+ gem 'pragma', github: 'pragmarb/pragma'
7
+ gem 'pragma-operation', github: 'pragmarb/pragma-operation'
8
+ gem 'pragma-contract', github: 'pragmarb/pragma-contract'
9
+ gem 'pragma-policy', github: 'pragmarb/pragma-policy'
10
+ gem 'pragma-decorator', github: 'pragmarb/pragma-decorator'
data/README.md CHANGED
@@ -29,29 +29,79 @@ $ gem install pragma-rails
29
29
 
30
30
  ## Usage
31
31
 
32
- The gem provides two modules which you can include in your controllers to integrate with Pragma.
32
+ ### Generators
33
33
 
34
- ### Basic controllers
34
+ This gem provides a `pragma:resource` generator for creating a new resource with the default CRUD
35
+ operations:
35
36
 
36
- The first module is `Pragma::Rails::Controller`. It gives you a `#run` method which you can call in
37
- your controller to run the provided Pragma operation:
37
+ ```console
38
+ $ rails g pragma:resource image
39
+ create app/resources/api/v1/image
40
+ create app/resources/api/v1/image/contract/base.rb
41
+ create app/resources/api/v1/image/contract/create.rb
42
+ create app/resources/api/v1/image/contract/update.rb
43
+ create app/resources/api/v1/image/decorator/instance.rb
44
+ create app/resources/api/v1/image/decorator/collection.rb
45
+ create app/resources/api/v1/image/operation/create.rb
46
+ create app/resources/api/v1/image/operation/destroy.rb
47
+ create app/resources/api/v1/image/operation/index.rb
48
+ create app/resources/api/v1/image/operation/show.rb
49
+ create app/resources/api/v1/image/operation/update.rb
50
+ create app/resources/api/v1/image/policy.rb
51
+ create app/controllers/api/v1/images_controller.rb
52
+ create spec/requests/api/v1/images_spec.rb
53
+ route namespace :api do
54
+ namespace :v1 do
55
+ resources :images, only: %i(index show create update destroy)
56
+ end
57
+ end
58
+ ```
59
+
60
+ You can also specify an API version (the default is 1):
61
+
62
+ ```console
63
+ $ rails g pragma:resource image -v 2
64
+ create app/resources/api/v2/image
65
+ create app/resources/api/v2/image/contract/base.rb
66
+ create app/resources/api/v2/image/contract/create.rb
67
+ create app/resources/api/v2/image/contract/update.rb
68
+ create app/resources/api/v2/image/decorator.rb
69
+ create app/resources/api/v2/image/operation/create.rb
70
+ create app/resources/api/v2/image/operation/destroy.rb
71
+ create app/resources/api/v2/image/operation/index.rb
72
+ create app/resources/api/v2/image/operation/show.rb
73
+ create app/resources/api/v2/image/operation/update.rb
74
+ create app/resources/api/v2/image/policy.rb
75
+ create app/controllers/api/v2/images_controller.rb
76
+ create spec/requests/api/v2/images_spec.rb
77
+ route namespace :api do
78
+ namespace :v2 do
79
+ resources :images, only: %i(index show create update destroy)
80
+ end
81
+ end
82
+
83
+ ```
84
+
85
+ ### Controllers
86
+
87
+ `Pragma::Rails::Controller` gives your controller the ability to run Pragma operations:
38
88
 
39
89
  ```ruby
40
90
  module API
41
91
  module V1
42
- class PostsController < ApplicationController
92
+ class ArticlesController < ApplicationController
43
93
  include Pragma::Rails::Controller
44
94
 
45
95
  def create
46
- run API::V1::Post::Operation::Create
96
+ run API::V1::Article::Operation::Create
47
97
  end
48
98
  end
49
99
  end
50
100
  end
51
101
  ```
52
102
 
53
- In the example above, `PostsController#create` will run the `API::V1::Post::Operation::Create`
54
- operation and respond with the status code, headers and resource output by the operation.
103
+ In the example above, `ArticlesController#create` will run the `API::V1::Article::Operation::Create`
104
+ operation and respond with the status code, headers and resource returned by the operation.
55
105
 
56
106
  By default, the `#params` method will be used as the operation's parameters and `#current_user`, if
57
107
  available, will be used as the operation's user. You can override these defaults by overriding the
@@ -60,11 +110,11 @@ available, will be used as the operation's user. You can override these defaults
60
110
  ```ruby
61
111
  module API
62
112
  module V1
63
- class PostsController < ApplicationController
113
+ class ArticlesController < ApplicationController
64
114
  include Pragma::Rails::Controller
65
115
 
66
116
  def create
67
- run API::V1::Post::Operation::Create
117
+ run API::V1::Article::Operation::Create
68
118
  end
69
119
 
70
120
  private
@@ -81,31 +131,40 @@ module API
81
131
  end
82
132
  ```
83
133
 
84
- ### Resource controllers
134
+ ### Resource Controllers
85
135
 
86
- Resource controllers abstract even more of the logic behind your controllers by inferring the
87
- operations supported by a resource and automagically providing controller actions that run them.
136
+ Resource controllers (provided by the `Pragma::Rails::ResourceController` module) abstract even more
137
+ of the logic behind your controllers by inferring the operations supported by a resource and
138
+ automatically providing controller actions that run them.
88
139
 
89
- Provided that the name of the controller and the name of the operation stay the same, the example
90
- above could be rewritten as:
140
+ With a resource controller, the example above could be rewritten as:
91
141
 
92
142
  ```ruby
93
143
  module API
94
144
  module V1
95
- class PostsController < ApplicationController
145
+ class ArticlesController < ApplicationController
96
146
  include Pragma::Rails::ResourceController
147
+
148
+ private
149
+
150
+ def operation_params
151
+ params.merge(my_additional: 'param')
152
+ end
153
+
154
+ def operation_user
155
+ User.authenticate_from params
156
+ end
97
157
  end
98
158
  end
99
159
  end
100
160
  ```
101
161
 
102
162
  You will still have to define a route to your `#create` action, of course, but you don't have to
103
- write the action anymore! This works with any actions, not only the default CRUD actions defined
104
- by Rails. So, for instance, if you have an `API::V1::Post::Operation::Publish` operation, a
105
- `#publish` action will be accessible in the `API::V1::PostsController` controller.
163
+ write the action anymore!
106
164
 
107
- Note that `Pragma::Rails::Controller` is included automatically when including
108
- `Pragma::Rails::ResourceController`.
165
+ This works with any actions, not only the default CRUD actions defined by Rails. So, for instance,
166
+ if you have an `API::V1::Article::Operation::Publish` operation, a `#publish` action will be
167
+ accessible in the `API::V1::ArticlesController` controller.
109
168
 
110
169
  ## Contributing
111
170
 
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pragma
4
+ class ResourceGenerator < ::Rails::Generators::NamedBase
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ class_option :version, type: :numeric, default: 1, desc: 'The API version to use', aliases: '-v'
8
+
9
+ def copy_initializer_file
10
+ copy_resource_files
11
+ copy_controller
12
+ copy_spec
13
+ generate_route
14
+ end
15
+
16
+ private
17
+
18
+ def copy_resource_files
19
+ directory 'resource/resource', "app/resources/api/v#{options['version']}/#{file_name}"
20
+ end
21
+
22
+ def copy_controller
23
+ template 'resource/controller.rb', "app/controllers/api/v#{options['version']}/#{file_name.pluralize}_controller.rb"
24
+ end
25
+
26
+ def copy_spec
27
+ template 'resource/spec.rb', "spec/requests/api/v#{options['version']}/#{file_name.pluralize}_spec.rb"
28
+ end
29
+
30
+ def class_path
31
+ ['api', "v#{options['version']}"]
32
+ end
33
+
34
+ # Taken from https://github.com/rails/rails/blob/master/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb
35
+ def generate_route
36
+ class_path.each_with_index do |namespace, index|
37
+ write("namespace :#{namespace} do", index + 1)
38
+ end
39
+
40
+ path_fragment = if file_name.include?('_')
41
+ ", path: '#{file_name.pluralize.tr('_', '-')}'"
42
+ end
43
+
44
+ write("resources :#{file_name.pluralize}, only: %i(index show create update destroy)#{path_fragment}", route_length + 1)
45
+
46
+ class_path.each_index do |index|
47
+ write('end', route_length - index)
48
+ end
49
+
50
+ # route prepends two spaces onto the front of the string that is passed, this corrects that.
51
+ # Also it adds a \n to the end of each line, as route already adds that we need to correct
52
+ # that too.
53
+ route route_string[2..-2]
54
+ end
55
+
56
+ def route_string
57
+ @route_string ||= ''
58
+ end
59
+
60
+ def write(str, indent)
61
+ @route_string = route_string + "#{' ' * indent}#{str}\n"
62
+ end
63
+
64
+ def route_length
65
+ class_path.length
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,6 @@
1
+ module API
2
+ module V<%= options['version'] %>
3
+ class <%= file_name.pluralize.camelcase %>Controller < ResourceController
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ module API
2
+ module V<%= options['version'] %>
3
+ module <%= file_name.camelcase %>
4
+ module Contract
5
+ class Base < Pragma::Contract::Base
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module API
2
+ module V<%= options['version'] %>
3
+ module <%= file_name.camelcase %>
4
+ module Contract
5
+ class Create < Base
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module API
2
+ module V<%= options['version'] %>
3
+ module <%= file_name.camelcase %>
4
+ module Contract
5
+ class Update < Base
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,15 @@
1
+ module API
2
+ module V<%= options['version'] %>
3
+ module <%= file_name.camelcase %>
4
+ module Decorator
5
+ class Collection < Pragma::Decorator::Base
6
+ feature Pragma::Decorator::Type
7
+ feature Pragma::Decorator::Collection
8
+ feature Pragma::Decorator::Pagination
9
+
10
+ decorate_with Instance
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ module API
2
+ module V<%= options['version'] %>
3
+ module <%= file_name.camelcase %>
4
+ module Decorator
5
+ class Instance < Pragma::Decorator::Base
6
+ feature Pragma::Decorator::Type
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ module API
2
+ module V<%= options['version'] %>
3
+ module <%= file_name.camelcase %>
4
+ module Operation
5
+ class Create < Pragma::Operation::Create
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module API
2
+ module V<%= options['version'] %>
3
+ module <%= file_name.camelcase %>
4
+ module Operation
5
+ class Destroy < Pragma::Operation::Destroy
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module API
2
+ module V<%= options['version'] %>
3
+ module <%= file_name.camelcase %>
4
+ module Operation
5
+ class Index < Pragma::Operation::Index
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module API
2
+ module V<%= options['version'] %>
3
+ module <%= file_name.camelcase %>
4
+ module Operation
5
+ class Show < Pragma::Operation::Show
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module API
2
+ module V<%= options['version'] %>
3
+ module <%= file_name.camelcase %>
4
+ module Operation
5
+ class Update < Pragma::Operation::Update
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,29 @@
1
+ module API
2
+ module V<%= options['version'] %>
3
+ module <%= file_name.camelcase %>
4
+ class Policy < Pragma::Policy::Base
5
+ class Scope < Pragma::Policy::Base::Scope
6
+ def resolve
7
+ scope.where('1 = 0')
8
+ end
9
+ end
10
+
11
+ def show?
12
+ false
13
+ end
14
+
15
+ def create?
16
+ false
17
+ end
18
+
19
+ def update?
20
+ false
21
+ end
22
+
23
+ def destroy?
24
+ false
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,99 @@
1
+ RSpec.describe '/api/v1/<%= file_name.pluralize.tr('_', '-') %>' do
2
+ describe 'GET /' do
3
+ subject { -> { get api_v1_<%= file_name.pluralize %>_path } }
4
+
5
+ let!(:<%= file_name %>) { create(:<%= file_name %>) }
6
+
7
+ it 'responds with 200 OK' do
8
+ subject.call
9
+ expect(last_response.status).to eq(200)
10
+ end
11
+
12
+ it 'responds with the <%= file_name.pluralize.humanize.downcase %>' do
13
+ subject.call
14
+ expect(parsed_response).to match_array([
15
+ a_hash_including('id' => <%= file_name %>.id)
16
+ ])
17
+ end
18
+ end
19
+
20
+ describe 'GET /:id' do
21
+ subject { -> { get api_v1_<%= file_name %>_path(<%= file_name %>) } }
22
+
23
+ let!(:<%= file_name %>) { create(:<%= file_name %>) }
24
+
25
+ it 'responds with 200 OK' do
26
+ subject.call
27
+ expect(last_response.status).to eq(200)
28
+ end
29
+
30
+ it 'responds with the <%= file_name.humanize.downcase %>' do
31
+ subject.call
32
+ expect(parsed_response).to match(a_hash_including(
33
+ 'id' => <%= file_name %>.id
34
+ ))
35
+ end
36
+ end
37
+
38
+ describe 'POST /' do
39
+ subject { -> { post api_v1_<%= file_name.pluralize %>_path, <%= file_name %>.to_json } }
40
+
41
+ let(:<%= file_name %>) { attributes_for(:<%= file_name %>) }
42
+
43
+ it 'responds with 201 Created' do
44
+ subject.call
45
+ expect(last_response.status).to eq(201)
46
+ end
47
+
48
+ it 'creates a new <%= file_name.humanize.downcase %>' do
49
+ expect(subject).to change(<%= file_name.camelcase %>, :count).by(1)
50
+ end
51
+
52
+ it 'responds with the new <%= file_name.humanize.downcase %>' do
53
+ subject.call
54
+ expect(parsed_response).to match(a_hash_including(<%= file_name %>.stringify_keys))
55
+ end
56
+ end
57
+
58
+ describe 'PATCH /:id' do
59
+ subject do
60
+ proc do
61
+ patch api_v1_<%= file_name %>_path(<%= file_name %>), new_<%= file_name %>.to_json
62
+ <%= file_name %>.reload
63
+ end
64
+ end
65
+
66
+ let!(:<%= file_name %>) { create(:<%= file_name %>) }
67
+ let(:new_<%= file_name %>) { attributes_for(:<%= file_name %>) }
68
+
69
+ it 'responds with 200 OK' do
70
+ subject.call
71
+ expect(last_response.status).to eq(200)
72
+ end
73
+
74
+ it 'updates the <%= file_name.humanize.downcase %>' do
75
+ subject.call
76
+ expect(<%= file_name %>.as_json).to match(a_hash_including(new_<%= file_name %>.stringify_keys))
77
+ end
78
+
79
+ it 'responds with the updated <%= file_name.humanize.downcase %>' do
80
+ subject.call
81
+ expect(parsed_response).to match(a_hash_including(new_<%= file_name %>.stringify_keys))
82
+ end
83
+ end
84
+
85
+ describe 'DELETE /:id' do
86
+ subject { -> { delete api_v1_<%= file_name %>_path(<%= file_name %>) } }
87
+
88
+ let!(:<%= file_name %>) { create(:<%= file_name %>) }
89
+
90
+ it 'deletes the <%= file_name.humanize.downcase %>' do
91
+ expect(subject).to change(<%= file_name.camelcase %>, :count).by(-1)
92
+ end
93
+
94
+ it 'responds with 204 No Content' do
95
+ subject.call
96
+ expect(last_response.status).to eq(204)
97
+ end
98
+ end
99
+ end
data/lib/pragma/rails.rb CHANGED
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'pragma'
3
4
  require 'rails'
4
5
 
5
6
  require 'pragma/rails/version'
6
7
  require 'pragma/rails/controller'
7
8
  require 'pragma/rails/resource_controller'
8
- require 'pragma/rails/hooks'
9
+
10
+ require 'generators/pragma/resource_generator' if defined?(::Rails::Generators)
9
11
 
10
12
  module Pragma
11
13
  # Ruby on Rails integration for the Pragma architecture.
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Pragma
3
4
  module Rails
4
5
  # This mixin should be included in a Rails controller to provide integration with Pragma
@@ -15,27 +16,31 @@ module Pragma
15
16
  #
16
17
  # @param operation_klass [Class|String] a subclass of +Pragma::Operation::Base+
17
18
  def run(operation_klass)
18
- begin
19
- result = operation_klass.to_s.constantize.call!(
20
- params: operation_params.to_unsafe_h,
21
- current_user: operation_user
22
- )
23
- rescue Interactor::Failure => e
24
- if e.context.pragma_operation_failure
25
- result = e.context
26
- else
27
- raise e
28
- end
19
+ operation_const = if operation_klass.is_a?(Class)
20
+ operation_klass
21
+ else
22
+ operation_klass.to_s.constantize
29
23
  end
30
24
 
31
- result.headers.each_pair do |key, value|
25
+ result = operation_const.call(
26
+ operation_params,
27
+ 'current_user' => operation_user
28
+ )
29
+
30
+ result['result.response'].headers.each_pair do |key, value|
32
31
  response.headers[key] = value
33
32
  end
34
33
 
35
- if result.resource
36
- render status: result.status, json: resource_to_json(result.resource).as_json
34
+ if result['result.response'].entity
35
+ render(
36
+ status: result['result.response'].status,
37
+ json: result['result.response'].entity.to_json(user_options: {
38
+ expand: params[:expand],
39
+ current_user: operation_user
40
+ })
41
+ )
37
42
  else
38
- head result.status
43
+ head result['result.response'].status
39
44
  end
40
45
  end
41
46
 
@@ -47,7 +52,7 @@ module Pragma
47
52
  #
48
53
  # @return [Hash]
49
54
  def operation_params
50
- params
55
+ params.to_unsafe_h
51
56
  end
52
57
 
53
58
  # Returns the currently authenticated user (for policies).
@@ -58,29 +63,6 @@ module Pragma
58
63
  def operation_user
59
64
  current_user if respond_to?(:current_user)
60
65
  end
61
-
62
- private
63
-
64
- def resource_to_json(resource)
65
- options = {
66
- user_options: {
67
- expand: params[:expand],
68
- current_user: operation_user
69
- }
70
- }
71
-
72
- if resource.is_a?(Array)
73
- resource.map do |instance|
74
- resource_to_json(instance)
75
- end
76
- else
77
- if resource.respond_to?(:to_hash)
78
- resource.method(:to_hash).arity.zero? ? resource.to_hash : resource.to_hash(options)
79
- else
80
- resource.as_json(options)
81
- end
82
- end
83
- end
84
66
  end
85
67
  end
86
68
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Pragma
3
4
  module Rails
4
5
  # Exposes CRUD operations on a resource through a Rails controller.
@@ -54,9 +55,9 @@ module Pragma
54
55
 
55
56
  def class_exists?(klass)
56
57
  begin
57
- klass.constantize
58
+ Object.const_get(klass)
58
59
  rescue NameError => e
59
- raise e unless e.message.include?("uninitialized constant #{klass}")
60
+ raise e unless e.message.end_with?("uninitialized constant #{klass}")
60
61
  end
61
62
 
62
63
  Object.const_defined?(klass)
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Pragma
3
4
  module Rails
4
- VERSION = '1.2.4'
5
+ VERSION = '2.0.0'
5
6
  end
6
7
  end
data/pragma-rails.gemspec CHANGED
@@ -1,4 +1,5 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  lib = File.expand_path('../lib', __FILE__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'pragma/rails/version'
@@ -20,13 +21,19 @@ Gem::Specification.new do |spec|
20
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
22
  spec.require_paths = ['lib']
22
23
 
23
- spec.add_dependency 'pragma', '~> 1.0'
24
+ spec.add_dependency 'pragma', '~> 2.0'
24
25
  spec.add_dependency 'rails', '>= 4.2', '< 6'
25
26
 
26
27
  spec.add_development_dependency 'bundler'
27
28
  spec.add_development_dependency 'rake'
28
- spec.add_development_dependency 'rspec'
29
+ spec.add_development_dependency 'rspec-rails'
29
30
  spec.add_development_dependency 'rubocop'
30
31
  spec.add_development_dependency 'rubocop-rspec'
31
32
  spec.add_development_dependency 'coveralls'
33
+ spec.add_development_dependency 'capybara'
34
+ spec.add_development_dependency 'factory_girl_rails'
35
+ spec.add_development_dependency 'database_cleaner'
36
+ spec.add_development_dependency 'faker'
37
+ spec.add_development_dependency 'pry-rails'
38
+ spec.add_development_dependency 'sqlite3'
32
39
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pragma-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.4
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alessandro Desantis
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-01-06 00:00:00.000000000 Z
11
+ date: 2017-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pragma
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: '2.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
26
+ version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rails
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -73,7 +73,7 @@ dependencies:
73
73
  - !ruby/object:Gem::Version
74
74
  version: '0'
75
75
  - !ruby/object:Gem::Dependency
76
- name: rspec
76
+ name: rspec-rails
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
79
  - - ">="
@@ -128,6 +128,90 @@ dependencies:
128
128
  - - ">="
129
129
  - !ruby/object:Gem::Version
130
130
  version: '0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: capybara
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ - !ruby/object:Gem::Dependency
146
+ name: factory_girl_rails
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ - !ruby/object:Gem::Dependency
160
+ name: database_cleaner
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ - !ruby/object:Gem::Dependency
174
+ name: faker
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ type: :development
181
+ prerelease: false
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ - !ruby/object:Gem::Dependency
188
+ name: pry-rails
189
+ requirement: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - ">="
192
+ - !ruby/object:Gem::Version
193
+ version: '0'
194
+ type: :development
195
+ prerelease: false
196
+ version_requirements: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
201
+ - !ruby/object:Gem::Dependency
202
+ name: sqlite3
203
+ requirement: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - ">="
206
+ - !ruby/object:Gem::Version
207
+ version: '0'
208
+ type: :development
209
+ prerelease: false
210
+ version_requirements: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
131
215
  description:
132
216
  email:
133
217
  - desa.alessandro@gmail.com
@@ -145,9 +229,22 @@ files:
145
229
  - Rakefile
146
230
  - bin/console
147
231
  - bin/setup
232
+ - lib/generators/pragma/resource_generator.rb
233
+ - lib/generators/pragma/templates/resource/controller.rb.tt
234
+ - lib/generators/pragma/templates/resource/resource/contract/base.rb.tt
235
+ - lib/generators/pragma/templates/resource/resource/contract/create.rb.tt
236
+ - lib/generators/pragma/templates/resource/resource/contract/update.rb.tt
237
+ - lib/generators/pragma/templates/resource/resource/decorator/collection.rb.tt
238
+ - lib/generators/pragma/templates/resource/resource/decorator/instance.rb.tt
239
+ - lib/generators/pragma/templates/resource/resource/operation/create.rb.tt
240
+ - lib/generators/pragma/templates/resource/resource/operation/destroy.rb.tt
241
+ - lib/generators/pragma/templates/resource/resource/operation/index.rb.tt
242
+ - lib/generators/pragma/templates/resource/resource/operation/show.rb.tt
243
+ - lib/generators/pragma/templates/resource/resource/operation/update.rb.tt
244
+ - lib/generators/pragma/templates/resource/resource/policy.rb.tt
245
+ - lib/generators/pragma/templates/resource/spec.rb.tt
148
246
  - lib/pragma/rails.rb
149
247
  - lib/pragma/rails/controller.rb
150
- - lib/pragma/rails/hooks.rb
151
248
  - lib/pragma/rails/resource_controller.rb
152
249
  - lib/pragma/rails/version.rb
153
250
  - pragma-rails.gemspec
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
- Pragma::Operation::Index.class_eval do
3
- def build_page_url(page)
4
- Rails.application.routes.url_helpers.url_for(params.merge(
5
- page_param => page,
6
- only_path: true
7
- ).symbolize_keys)
8
- end
9
- end