Skip to content

Commit

Permalink
Improve work with model and object (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
afuno committed Aug 29, 2024
1 parent dfbd5b9 commit 326fe2c
Show file tree
Hide file tree
Showing 17 changed files with 527 additions and 256 deletions.
14 changes: 7 additions & 7 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ PATH
datory (1.0.0)
activesupport (>= 5.1, < 8.0)
i18n (~> 1.14)
servactory (>= 2.6.0)
servactory (>= 2.8.0)
terminal-table (>= 3.0)
zeitwerk (~> 2.6)

GEM
remote: https://rubygems.org/
specs:
abbrev (0.1.2)
activesupport (7.1.3.3)
activesupport (7.1.3.4)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
Expand All @@ -29,15 +29,15 @@ GEM
ast (2.4.2)
base64 (0.2.0)
bigdecimal (3.1.8)
concurrent-ruby (1.2.3)
concurrent-ruby (1.3.3)
connection_pool (2.4.1)
diff-lcs (1.5.1)
drb (2.2.1)
i18n (1.14.5)
concurrent-ruby (~> 1.0)
json (2.7.2)
language_server-protocol (3.17.0.3)
minitest (5.23.0)
minitest (5.24.1)
mutex_m (0.2.0)
parallel (1.24.0)
parser (3.3.0.5)
Expand Down Expand Up @@ -93,8 +93,8 @@ GEM
rubocop-rspec_rails (2.28.3)
rubocop (~> 1.40)
ruby-progressbar (1.13.0)
servactory (2.6.2)
activesupport (>= 5.1, < 7.2)
servactory (2.8.0)
activesupport (>= 5.1, < 8.0)
i18n (~> 1.14)
zeitwerk (~> 2.6)
terminal-table (3.0.2)
Expand All @@ -103,7 +103,7 @@ GEM
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (2.5.0)
zeitwerk (2.6.14)
zeitwerk (2.6.16)

PLATFORMS
ruby
Expand Down
112 changes: 58 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,38 +52,42 @@ form.serialize # => { ... }

```ruby
class SerialDto < Datory::Base
uuid :id
uuid! :id

string :status
string :title
string! :status
string! :title

one :poster, include: ImageDto
one! :poster, include: ImageDto

one :ratings, include: RatingsDto
one! :ratings, include: RatingsDto

many :countries, include: CountryDto
many :genres, include: GenreDto
many :seasons, include: SeasonDto
many! :countries, include: CountryDto
many! :genres, include: GenreDto
many! :seasons, include: SeasonDto

date :premieredOn, to: :premiered_on
date! :premieredOn, to: :premiered_on
end
```

```ruby
class SeasonDto < Datory::Base
uuid :id
uuid :serial_id
uuid! :id
uuid! :serialId, to: :serial_id

integer :number
integer! :number

many :episodes, include: EpisodeDto
many! :episodes, include: EpisodeDto

date :premiered_on
date! :premieredOn, to: :premiered_on
date? :endedOn, to: :ended_on
end
```

## Attribute declaration

Using the `!` sign means that the attribute is required.
The optionality of an attribute is indicated using the `?` sign.

### Basic

#### attribute
Expand All @@ -92,84 +96,84 @@ end
attribute :uuid, from: String, to: :id, as: String, format: :uuid
```

#### string
#### string!

```ruby
string :uuid, to: :id
string! :uuid, to: :id
```

#### integer
#### integer!

```ruby
integer :rating, min: 1, max: 10
integer! :rating, min: 1, max: 10
```

#### float
#### float!

```ruby
float :rating
float! :rating
```

#### boolean
#### boolean!

```ruby
boolean :default
boolean! :default
```

### Helpers

#### uuid
#### uuid!

It will also check that the value matches the UUID format.

```ruby
uuid :id
uuid! :id
```

#### money
#### money!

It will prepare two attributes `*_cents` and `*_currency`.

```ruby
money :box_office
money! :box_office
```

#### duration
#### duration!

```ruby
duration :episode_duration
duration! :episode_duration
```

#### date
#### date!

```ruby
date :premiered_on
date! :premiered_on
```

#### time
#### time!

```ruby
time :premiered_at
time! :premiered_at
```

#### datetime
#### datetime!

```ruby
time :premiered_at
time! :premiered_at
```

### Nesting

#### one
#### one!

```ruby
one :poster, include: ImageDto
one! :poster, include: ImageDto
```

#### many
#### many!

```ruby
many :seasons, include: SeasonDto
many! :seasons, include: SeasonDto
```

## Object information
Expand All @@ -181,7 +185,7 @@ SerialDto.info
```

```
#<Datory::Info::Result:0x0000000124aa7bc8 @attributes={:id=>{:from=>{:name=>:id, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>:uuid}, :to=>{:name=>:id, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>:uuid, :required=>true, :include=>nil}}, :status=>{:from=>{:name=>:status, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil}, :to=>{:name=>:status, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil, :required=>true, :include=>nil}}, :title=>{:from=>{:name=>:title, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil}, :to=>{:name=>:title, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil, :required=>true, :include=>nil}}, :poster=>{:from=>{:name=>:poster, :type=>Hash, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil}, :to=>{:name=>:poster, :type=>[Datory::Result, Hash], :min=>nil, :max=>nil, :consists_of=>false, :format=>nil, :required=>true, :include=>Usual::Example1::Image}}, :ratings=>{:from=>{:name=>:ratings, :type=>Hash, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil}, :to=>{:name=>:ratings, :type=>[Datory::Result, Hash], :min=>nil, :max=>nil, :consists_of=>false, :format=>nil, :required=>true, :include=>Usual::Example1::Ratings}}, :countries=>{:from=>{:name=>:countries, :type=>Array, :min=>nil, :max=>nil, :consists_of=>[Datory::Result, Hash], :format=>nil}, :to=>{:name=>:countries, :type=>Array, :min=>nil, :max=>nil, :consists_of=>[Datory::Result, Hash], :format=>nil, :required=>true, :include=>Usual::Example1::Country}}, :genres=>{:from=>{:name=>:genres, :type=>Array, :min=>nil, :max=>nil, :consists_of=>[Datory::Result, Hash], :format=>nil}, :to=>{:name=>:genres, :type=>Array, :min=>nil, :max=>nil, :consists_of=>[Datory::Result, Hash], :format=>nil, :required=>true, :include=>Usual::Example1::Genre}}, :seasons=>{:from=>{:name=>:seasons, :type=>Array, :min=>nil, :max=>nil, :consists_of=>[Datory::Result, Hash], :format=>nil}, :to=>{:name=>:seasons, :type=>Array, :min=>nil, :max=>nil, :consists_of=>[Datory::Result, Hash], :format=>nil, :required=>true, :include=>Usual::Example1::Season}}, :premieredOn=>{:from=>{:name=>:premieredOn, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>:date}, :to=>{:name=>:premiered_on, :type=>Date, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil, :required=>true, :include=>nil}}}>
#<Datory::Info::Result:0x0000000128a33c38 @attributes={:id=>{:from=>{:name=>:id, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>:uuid}, :to=>{:name=>:id, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>:uuid, :required=>true, :default=>nil, :include=>nil}}, :status=>{:from=>{:name=>:status, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil}, :to=>{:name=>:status, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil, :required=>true, :default=>nil, :include=>nil}}, :title=>{:from=>{:name=>:title, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil}, :to=>{:name=>:title, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil, :required=>true, :default=>nil, :include=>nil}}, :poster=>{:from=>{:name=>:poster, :type=>[Usual::Example1::Image, Hash], :min=>nil, :max=>nil, :consists_of=>false, :format=>nil}, :to=>{:name=>:poster, :type=>[Usual::Example1::Image, Hash], :min=>nil, :max=>nil, :consists_of=>false, :format=>nil, :required=>true, :default=>nil, :include=>Usual::Example1::Image}}, :ratings=>{:from=>{:name=>:ratings, :type=>[Usual::Example1::Ratings, Hash], :min=>nil, :max=>nil, :consists_of=>false, :format=>nil}, :to=>{:name=>:ratings, :type=>[Usual::Example1::Ratings, Hash], :min=>nil, :max=>nil, :consists_of=>false, :format=>nil, :required=>true, :default=>nil, :include=>Usual::Example1::Ratings}}, :countries=>{:from=>{:name=>:countries, :type=>Array, :min=>nil, :max=>nil, :consists_of=>[Usual::Example1::Country, Hash], :format=>nil}, :to=>{:name=>:countries, :type=>Array, :min=>nil, :max=>nil, :consists_of=>[Usual::Example1::Country, Hash], :format=>nil, :required=>true, :default=>nil, :include=>Usual::Example1::Country}}, :genres=>{:from=>{:name=>:genres, :type=>Array, :min=>nil, :max=>nil, :consists_of=>[Usual::Example1::Genre, Hash], :format=>nil}, :to=>{:name=>:genres, :type=>Array, :min=>nil, :max=>nil, :consists_of=>[Usual::Example1::Genre, Hash], :format=>nil, :required=>true, :default=>nil, :include=>Usual::Example1::Genre}}, :seasons=>{:from=>{:name=>:seasons, :type=>Array, :min=>nil, :max=>nil, :consists_of=>[Usual::Example1::Season, Hash], :format=>nil}, :to=>{:name=>:seasons, :type=>Array, :min=>nil, :max=>nil, :consists_of=>[Usual::Example1::Season, Hash], :format=>nil, :required=>true, :default=>nil, :include=>Usual::Example1::Season}}, :premieredOn=>{:from=>{:name=>:premieredOn, :type=>String, :min=>nil, :max=>nil, :consists_of=>false, :format=>:date}, :to=>{:name=>:premiered_on, :type=>Date, :min=>nil, :max=>nil, :consists_of=>false, :format=>nil, :required=>true, :default=>nil, :include=>nil}}}>
```

### Describe
Expand All @@ -193,21 +197,21 @@ SerialDto.describe
```

```
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| SerialDto |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Attribute | From | To | As | Include |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| id | String | id | String | |
| status | String | status | String | |
| title | String | title | String | |
| poster | Hash | poster | [Datory::Result, Hash] | ImageDto |
| ratings | Hash | ratings | [Datory::Result, Hash] | RatingsDto |
| countries | Array | countries | Array | CountryDto |
| genres | Array | genres | Array | GenreDto |
| seasons | Array | seasons | Array | SeasonDto |
| premieredOn | String | premiered_on | Date | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| SerialDto |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Attribute | From | To | As | Include |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| id | String | id | String | |
| status | String | status | String | |
| title | String | title | String | |
| poster | [ImageDto, Hash] | poster | [ImageDto, Hash] | ImageDto | |
| ratings | [RatingsDto, Hash] | ratings | [RatingsDto, Hash] | RatingsDto | |
| countries | Array | countries | Array | CountryDto |
| genres | Array | genres | Array | GenreDto |
| seasons | Array | seasons | Array | SeasonDto |
| premieredOn | String | premiered_on | Date | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```

## Contributing
Expand Down
2 changes: 1 addition & 1 deletion datory.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Gem::Specification.new do |spec|

spec.add_runtime_dependency "activesupport", ">= 5.1", "< 8.0"
spec.add_runtime_dependency "i18n", "~> 1.14"
spec.add_runtime_dependency "servactory", ">= 2.6.0"
spec.add_runtime_dependency "servactory", ">= 2.8.0"
spec.add_runtime_dependency "terminal-table", ">= 3.0"
spec.add_runtime_dependency "zeitwerk", "~> 2.6"

Expand Down
8 changes: 4 additions & 4 deletions lib/datory/attributes/attribute.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ def input_serialization_options # rubocop:disable Metrics/AbcSize, Metrics/Metho

def output_serialization_options # rubocop:disable Metrics/AbcSize
hash = {
consists_of: to.consists_of == Hash ? Datory::Result : from.consists_of,
type: to.type == Datory::Result ? Hash : from.type
consists_of: from.consists_of,
type: from.type
}

hash[:min] = from.min if from.min.present?
Expand Down Expand Up @@ -97,8 +97,8 @@ def input_deserialization_options # rubocop:disable Metrics/MethodLength, Metric

def output_deserialization_options # rubocop:disable Metrics/AbcSize
hash = {
consists_of: from.consists_of == Hash ? Datory::Result : to.consists_of,
type: from.type == Hash ? Datory::Result : to.type
consists_of: to.consists_of,
type: to.type
}

hash[:min] = to.min if to.min.present?
Expand Down
6 changes: 3 additions & 3 deletions lib/datory/attributes/collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ module Datory
module Attributes
class Collection
extend Forwardable
def_delegators :@collection, :<<, :each, :map, :filter, :to_h, :merge
def_delegators :@collection, :<<, :each, :map, :filter, :to_h, :merge, :find

def initialize(collection = Set.new)
@collection = collection
end

def names
map(&:name)
def find_by(name:)
find { |attribute| attribute.from.name == name }
end

def internal_names
Expand Down
4 changes: 3 additions & 1 deletion lib/datory/attributes/deserialization/service_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ def initialize(context, incoming_attributes, collection_of_attributes)
def build!
ServiceFactory.create(@context.class, @collection_of_attributes)

builder_class.call!(**@incoming_attributes)
result = builder_class.call!(**@incoming_attributes)

@context.class.serialization.new(**result.to_h)
end

private
Expand Down
12 changes: 6 additions & 6 deletions lib/datory/attributes/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ def one!(name, include:, to: nil)
attribute(
name,
to: to.presence || name,
from: Hash,
from: [include, Hash],
include: include,
as: [Datory::Result, Hash]
as: [include, Hash]
)
end
# NOTE: This will most likely be marked as deprecated in the future in favor of `one!`
Expand All @@ -39,9 +39,9 @@ def one?(name, include:, to: nil)
attribute(
name,
to: to.presence || name,
from: [Hash, NilClass],
from: [include, Hash, NilClass],
include: include,
as: [Datory::Result, Hash, NilClass],
as: [include, Hash, NilClass],
required: false
)
end
Expand All @@ -51,7 +51,7 @@ def many!(name, include:, to: nil)
name,
to: to.presence || name,
from: Array,
consists_of: [Datory::Result, Hash],
consists_of: [include, Hash],
include: include,
as: Array
)
Expand All @@ -64,7 +64,7 @@ def many?(name, include:, to: nil)
name,
to: to.presence || name,
from: Array,
consists_of: [Datory::Result, Hash],
consists_of: [include, Hash],
include: include,
as: Array,
required: false,
Expand Down
8 changes: 4 additions & 4 deletions lib/datory/attributes/form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ def update(**attributes)
raise_misuse "The `update` method cannot be used with a collection. Instead, use the `update_by` method."
end

found_keys = model.keys & attributes.keys
found_keys = model.send(:keys) & attributes.keys

reset!

model.merge!(attributes.slice(*found_keys))
model.send(:merge!, attributes.slice(*found_keys))
end

def update_by(index, **attributes) # rubocop:disable Metrics/MethodLength
Expand All @@ -35,9 +35,9 @@ def update_by(index, **attributes) # rubocop:disable Metrics/MethodLength

model.map!.with_index do |model_item, model_index|
if model_index == index
found_keys = model_item.keys & attributes.keys
found_keys = model_item.send(:keys) & attributes.keys

model_item.merge(attributes.slice(*found_keys))
model_item.send(:merge, attributes.slice(*found_keys))
else
model_item
end
Expand Down
Loading

0 comments on commit 326fe2c

Please sign in to comment.