pragma-contract 2.0.1 → 2.1.1

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
2
  SHA256:
3
- metadata.gz: 65bb088e2e5f2bea1013369379af3335d4c02b381775d376701c0453b8e8f17c
4
- data.tar.gz: e2bca105d4a8cc7c3980c8f927bea2468b33a5d342ace9574f5e41afb0a8fc04
3
+ metadata.gz: ee1d19808a18f852a7889126b040644ff9998dffb001fa385979752d11c1963b
4
+ data.tar.gz: 494b6b03190618620e2795ef9f61e076f61f1891d20bc1b375b8b06829c84a21
5
5
  SHA512:
6
- metadata.gz: c9a7cf260d36af1a576d4fa6f16c913b0a643dc4ec67a735a5760213efde02ccd94223b35a43ff601b72755d393a8045402e0ad03281c339c78aa4b93c3fcf36
7
- data.tar.gz: 07afc3dcc218d6f3208b18f28456327ea7a9850452c41cae0c96f9022a4c4cfe68a6b0808d436cb37651bc60462f17a7601131ae2e80527b7d8ef8c57428645f
6
+ metadata.gz: de13ebd9f314c416d083a049cb5a3d853bcdc9703d8b27b5945c79dc13eb558cd7c067dc65f3e8ed51c360b36f905be423a22d54a4edff76eae9aed5c57a5a49
7
+ data.tar.gz: ba6b2a7bced2b111976b1a6e8a4d5ba766df4721ce974ab47625018d1773eb19f6d1ff31a78a2d8c582e969c527419ccb0508fce4f0ab4fb67b414dade196604
@@ -5,6 +5,7 @@ AllCops:
5
5
  Include:
6
6
  - '**/Gemfile'
7
7
  - '**/Rakefile'
8
+ - '**/*.rb'
8
9
  Exclude:
9
10
  - 'bin/*'
10
11
  - 'db/**/*'
@@ -77,3 +78,6 @@ Style/Documentation:
77
78
  Naming/FileName:
78
79
  Exclude:
79
80
  - '*.gemspec'
81
+
82
+ Metrics/AbcSize:
83
+ Enabled: false
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.1.1]
11
+
12
+ ### Fixed
13
+
14
+ - Fixed `property` expecting two arguments
15
+
16
+ ## [2.1.0]
17
+
18
+ ### Added
19
+
20
+ - Implemented the ability to find records when coercing contracts
21
+
10
22
  ## [2.0.1]
11
23
 
12
24
  ### Fixed
@@ -23,6 +35,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
23
35
 
24
36
  First Pragma 2 release.
25
37
 
26
- [Unreleased]: https://github.com/pragmarb/pragma-contract/compare/v2.0.1...HEAD
38
+ [Unreleased]: https://github.com/pragmarb/pragma-contract/compare/v2.1.1...HEAD
39
+ [2.1.1]: https://github.com/pragmarb/pragma-contract/compare/v2.1.0...v2.1.1
40
+ [2.1.0]: https://github.com/pragmarb/pragma-contract/compare/v2.0.1...v2.1.0
27
41
  [2.0.1]: https://github.com/pragmarb/pragma-contract/compare/v2.0.0...v2.0.1
28
42
  [2.0.0]: https://github.com/pragmarb/pragma-contract/compare/v0.1.0...v2.0.0
data/README.md CHANGED
@@ -92,6 +92,60 @@ module API
92
92
  end
93
93
  ```
94
94
 
95
+ ### Model finders
96
+
97
+ This is a common pattern in API contracts:
98
+
99
+ ```ruby
100
+ module API
101
+ module V1
102
+ module Invoice
103
+ module Contract
104
+ class Base < Pragma::Contract::Base
105
+ property :customer
106
+
107
+ def customer=(val)
108
+ super ::Customer.find_by(id: val)
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ ```
116
+
117
+ Pragma::Contract provides a shorthand syntax:
118
+
119
+ ```ruby
120
+ module API
121
+ module V1
122
+ module Invoice
123
+ module Contract
124
+ class Base < Pragma::Contract::Base
125
+ property :customer, type: Customer
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+ ```
132
+
133
+ You can also specify a custom column to find by!
134
+
135
+ ```ruby
136
+ module API
137
+ module V1
138
+ module Invoice
139
+ module Contract
140
+ class Base < Pragma::Contract::Base
141
+ property :customer, type: Customer, by: :email
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
147
+ ```
148
+
95
149
  ## Contributing
96
150
 
97
151
  Bug reports and pull requests are welcome on GitHub at https://github.com/pragmarb/pragma-contract.
@@ -1,18 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'adaptor'
3
4
  require 'dry-validation'
4
5
  require 'dry-types'
5
6
  require 'reform'
6
7
 
7
8
  require 'pragma/contract/version'
9
+
8
10
  require 'pragma/contract/coercion'
11
+
12
+ require 'pragma/contract/model_finder/base'
13
+ require 'pragma/contract/model_finder/active_record'
14
+ require 'pragma/contract/model_finder'
15
+
9
16
  require 'pragma/contract/base'
17
+
10
18
  require 'pragma/contract/types'
11
19
 
12
20
  module Pragma
13
21
  # Form objects on steroids for your HTTP API.
14
- #
15
- # @author Alessandro Desantis
16
22
  module Contract
17
23
  end
18
24
  end
@@ -14,6 +14,7 @@ module Pragma
14
14
  feature Reform::Form::Coercion
15
15
  feature Pragma::Contract::Coercion
16
16
  feature Reform::Form::Dry
17
+ feature Pragma::Contract::ModelFinder
17
18
 
18
19
  property :current_user, virtual: true
19
20
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pragma
4
+ module Contract
5
+ module ModelFinder
6
+ include Adaptor::Loader
7
+ register ActiveRecord
8
+
9
+ FINDER_OPTIONS = [:by].freeze
10
+
11
+ def self.included(klass)
12
+ klass.extend ClassMethods
13
+ end
14
+
15
+ module ClassMethods
16
+ def property(name, options = {})
17
+ return super if !options[:type] || options[:type].is_a?(Dry::Types::Type)
18
+
19
+ property(name, Hash[options.reject { |k, _| k == :type }])
20
+
21
+ define_method("#{name}=") do |value|
22
+ finder = Pragma::Contract::ModelFinder.load_adaptor!(
23
+ options[:type],
24
+ Hash[options.select { |k, _| FINDER_OPTIONS.include?(k.to_sym) }]
25
+ )
26
+
27
+ super finder.find(value)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pragma
4
+ module Contract
5
+ module ModelFinder
6
+ class ActiveRecord < Base
7
+ class << self
8
+ def supports?(klass)
9
+ defined?(::ActiveRecord::Base) && klass < ::ActiveRecord::Base
10
+ end
11
+ end
12
+
13
+ def find(value)
14
+ klass.find_by(options[:by] => value)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pragma
4
+ module Contract
5
+ module ModelFinder
6
+ class Base
7
+ include Adaptor
8
+
9
+ class << self
10
+ def supports?(_klass)
11
+ fail NotImplementedError
12
+ end
13
+ end
14
+
15
+ attr_reader :klass, :options
16
+
17
+ def initialize(klass, options)
18
+ @klass = klass
19
+ @options = { by: :id }.merge(options)
20
+ end
21
+
22
+ def find(_value)
23
+ fail NotImplementedError
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Pragma
4
4
  module Contract
5
- VERSION = '2.0.1'
5
+ VERSION = '2.1.1'
6
6
  end
7
7
  end
@@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
22
  spec.require_paths = ['lib']
23
23
 
24
+ spec.add_dependency 'adaptor', '~> 0.2'
24
25
  spec.add_dependency 'dry-types', '~> 0.12.0'
25
26
  spec.add_dependency 'dry-validation', '~> 0.11.1'
26
27
  spec.add_dependency 'reform', '~> 2.2'
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pragma-contract
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.1
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-06-09 00:00:00.000000000 Z
11
+ date: 2018-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: adaptor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.2'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: dry-types
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -157,6 +171,9 @@ files:
157
171
  - lib/pragma/contract.rb
158
172
  - lib/pragma/contract/base.rb
159
173
  - lib/pragma/contract/coercion.rb
174
+ - lib/pragma/contract/model_finder.rb
175
+ - lib/pragma/contract/model_finder/active_record.rb
176
+ - lib/pragma/contract/model_finder/base.rb
160
177
  - lib/pragma/contract/types.rb
161
178
  - lib/pragma/contract/version.rb
162
179
  - pragma-contract.gemspec