Skip to content

Commit ee1f29f

Browse files
committed
Improve UPGRADING.md instructions for custom types
* Provide an example for taking an existing type and porting it to the dry-types. This would have saved me some time. * Removed examples of using `Virtus.model`. It seems confusing to support dry-types and Virtus at the same time. Closes #2012
1 parent 0219c75 commit ee1f29f

File tree

1 file changed

+36
-17
lines changed

1 file changed

+36
-17
lines changed

UPGRADING.md

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,38 +9,57 @@ After adding dry-types, Ruby 2.4 or newer is required.
99

1010
#### Coercion
1111

12-
[Virtus](https://github.com/solnic/virtus) has been replaced by [dry-types](https://dry-rb.org/gems/dry-types/1.2/) for parameter coercion. If your project depends on Virtus, explicitly add it to your `Gemfile`. Also, if Virtus is used for defining custom types
12+
[Virtus](https://github.com/solnic/virtus) has been replaced by
13+
[dry-types](https://dry-rb.org/gems/dry-types/1.2/) for parameter
14+
coercion. If your project depends on Virtus outside of Grape, explicitly
15+
add it to your `Gemfile`.
16+
17+
Here's an example of how to migrate a custom type from Virtus to dry-types:
1318

1419
```ruby
15-
class User
16-
include Virtus.model
20+
# Legacy Grape parser
21+
class SecureUriType < Virtus::Attribute
22+
def coerce(input)
23+
URI.parse value
24+
end
1725

18-
attribute :id, Integer
19-
attribute :name, String
26+
def value_coerced?(input)
27+
value.is_a? String
28+
end
2029
end
2130

22-
# somewhere in your API
2331
params do
24-
requires :user, type: User
32+
requires :secure_uri, type: SecureUri
2533
end
2634
```
2735

28-
Add a class-level `parse` method to the model:
36+
To use dry-types, we need to:
2937

30-
```ruby
31-
class User
32-
include Virtus.model
38+
1. Remove the inheritance of `Virtus::Attribute`
39+
1. Rename `coerce` to `self.parse`
40+
1. Rename `value_coerced?` to `self.parsed?`
3341

34-
attribute :id, Integer
35-
attribute :name, String
42+
The custom type must have a class-level `parse` method to the model. A
43+
class-level `parsed?` is needed if the parsed type differs from the
44+
defined type. In the example below, since `SecureUri` is not the same
45+
as `URI::HTTPS`, `self.parsed?` is needed:
3646

37-
def self.parse(attrs)
38-
new(attrs)
47+
```ruby
48+
# New dry-types parser
49+
class SecureUri
50+
def self.parse(value)
51+
URI.parse value
52+
end
53+
54+
def self.parsed?(value)
55+
value.is_a? URI::HTTPS
3956
end
4057
end
41-
```
4258

43-
Custom types which don't depend on Virtus don't require any changes.
59+
params do
60+
requires :secure_uri, type: SecureUri
61+
end
62+
```
4463

4564
#### Ensure that Array types have explicit coercions
4665

0 commit comments

Comments
 (0)