team_fastlane-domain_driven_design 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.adoc +39 -0
- data/README.adoc +7 -0
- data/lib/team_fastlane/domain_driven_design/entity_base.rb +46 -0
- data/lib/team_fastlane/domain_driven_design/repository_base.rb +128 -0
- data/lib/team_fastlane/domain_driven_design/version.rb +7 -0
- data/lib/team_fastlane/domain_driven_design.rb +10 -0
- metadata +51 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6254016e8961513cb7097633e77fdda46e6bfb849a7776dc551f6a1531846256
|
4
|
+
data.tar.gz: ce3a1a9a7cbcf13246efd889dc9af63e10f2d4bd7873b8ca170b6842376c6196
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9a16818fc6edd7c088aa458b5f83f86f869f402f31f21b3c77d2c518ff96edda5fe6efd76320a7456372364cfa0301fdb0daa570f83da445669bd27420d3e5b8
|
7
|
+
data.tar.gz: b64e3c3d4df0ec1e3fe68ff3e92e5ff7c836e2191a398fe4cd978130b9a2d6961dfc7cbb61d3fb1b89446a1fb4e4de98f6001dd73dbc8e119de1b2faf6c868c7
|
data/CHANGELOG.adoc
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
= Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on https://keepachangelog.com[Keep a Changelog],
|
6
|
+
and this project adheres to https://semver.org[Semantic Versioning].
|
7
|
+
|
8
|
+
== Unreleased
|
9
|
+
|
10
|
+
== [1.0.0] - 2023-08-01
|
11
|
+
=== Changed
|
12
|
+
Renamed and restructured for release on rubygems
|
13
|
+
|
14
|
+
== [0.0.5] - 2022-01-03
|
15
|
+
=== Changed
|
16
|
+
- Small refactoring to comply to rubocop
|
17
|
+
|
18
|
+
== [0.0.4] - 2020-06-10
|
19
|
+
=== Added
|
20
|
+
- A basic readme
|
21
|
+
=== Changed
|
22
|
+
- Adjusted changelog more to keep-a-changelog-recommendation
|
23
|
+
- Cleanup gemspec
|
24
|
+
- Cleanup gem structure to match best practices
|
25
|
+
|
26
|
+
== [0.0.3] - 2020-05-19
|
27
|
+
=== Bugfix
|
28
|
+
- Applied Rubocop to all files
|
29
|
+
|
30
|
+
== [0.0.2] - 2020-05-18
|
31
|
+
=== Bugfix
|
32
|
+
- Added the possibility to require the Gem instead of the single lib files.
|
33
|
+
|
34
|
+
== [0.0.1] - 2020-05-18
|
35
|
+
=== Added
|
36
|
+
- Initial Gem version extracted from the Fastlane Backend.
|
37
|
+
|
38
|
+
The format is based on https://keepachangelog.com[Keep a Changelog],
|
39
|
+
and this project adheres to https://semver.org[Semantic Versioning].
|
data/README.adoc
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TeamFastlane
|
4
|
+
# This is the base for all domain-driven design entities.
|
5
|
+
# A entity represents a unique object of a specific type in the domain, e.g. a customer. Entities won't be defined by
|
6
|
+
# their attributes but their unique identity.
|
7
|
+
#
|
8
|
+
# Entities are used most of the times to implement the business logic for a given domain, they don't know anything
|
9
|
+
# about outside systems (like persistence layer) and can only work with their attributes and the given parameters of
|
10
|
+
# the called method.
|
11
|
+
#
|
12
|
+
# To make use of this include it in your entity.
|
13
|
+
#
|
14
|
+
# @example How to include properly
|
15
|
+
# class TestEntity
|
16
|
+
# include DomainDrivenDesign::EntityBase
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# @ddd_base
|
20
|
+
# @author Robert Kranz
|
21
|
+
module DomainDrivenDesign
|
22
|
+
module EntityBase
|
23
|
+
extend ActiveSupport::Concern
|
24
|
+
include ActiveModel::Model
|
25
|
+
include Comparable
|
26
|
+
|
27
|
+
def <=>(other)
|
28
|
+
return id <=> other.id if respond_to?(:id)
|
29
|
+
|
30
|
+
attributes <=> other.attributes
|
31
|
+
end
|
32
|
+
|
33
|
+
def attributes
|
34
|
+
instance_values.transform_values do |value|
|
35
|
+
value.respond_to?(:attributes) ? value.attributes : value
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class_methods do
|
40
|
+
def repository
|
41
|
+
@repository ||= "#{name}Repository".constantize
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TeamFastlane
|
4
|
+
# This is the base for all domain-driven design repositories.
|
5
|
+
# A repository bridges the gap between business ({EntityBase}) and persistence layer (database). It encapsulates
|
6
|
+
# storage, retrieval and search behavior for an amount of business objects.
|
7
|
+
#
|
8
|
+
# It achieves this by providing methods for object handling on the one hand and besides that also provides the mapping
|
9
|
+
# from the data structure to the business objects.
|
10
|
+
#
|
11
|
+
# This is not the right place to implement specific sql finder or similar, use the actual ActiveRecord model for this.
|
12
|
+
# Methods in here lean more to complex joins and chaining model methods together to retrieve or store its business
|
13
|
+
# objects.
|
14
|
+
#
|
15
|
+
# This is also not the place to define business logic, see {EntityBase} for this.
|
16
|
+
#
|
17
|
+
# To make use of this extend your repository with it.
|
18
|
+
#
|
19
|
+
# @example How to extend properly
|
20
|
+
# module TestRepository
|
21
|
+
# extend DomainDrivenDesign::RepositoryBase
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# @ddd_base
|
25
|
+
# @author Robert Kranz
|
26
|
+
module DomainDrivenDesign
|
27
|
+
module RepositoryBase
|
28
|
+
# Constructs an entity from the given data. The given data could either be an ActiveRecord model, or another data
|
29
|
+
# container class. Please be careful to adjust your mapping accordingly if you change the type of the data.
|
30
|
+
def build_entity(data)
|
31
|
+
entity.new map_arguments(entity_mapping, data)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Represents the managed entity class, will be retrieved by reflecting over the repository name.
|
35
|
+
# For example consider this repository.
|
36
|
+
#
|
37
|
+
# module TestFeature
|
38
|
+
# module TestRepository
|
39
|
+
# extend DomainDrivenDesign::RepositoryBase
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# Calling the entity method (with send cause it's private) we receive the Test entity.
|
44
|
+
# TestFeature::TestRepository.send :entity #=> TestFeature::Test
|
45
|
+
#
|
46
|
+
# It's possible to set this to something else instead, but it's highly discouraged.
|
47
|
+
def entity
|
48
|
+
@entity ||= name.gsub('Repository', '').constantize
|
49
|
+
end
|
50
|
+
|
51
|
+
def entity=(class_name)
|
52
|
+
@entity = class_name
|
53
|
+
end
|
54
|
+
|
55
|
+
protected
|
56
|
+
|
57
|
+
# Can be used to explicitly demand, that a finder method should only be called,
|
58
|
+
# if the object requested surely exists.
|
59
|
+
# For example for use cases where something should be done with an existing customer.
|
60
|
+
def ensure_existence(record)
|
61
|
+
raise ActiveRecord::RecordNotFound unless record
|
62
|
+
|
63
|
+
record
|
64
|
+
end
|
65
|
+
|
66
|
+
# This can be used to set the mapping for the {#build_entity} method or to retrieve it.
|
67
|
+
# @example Only data methods
|
68
|
+
# module TestFeature
|
69
|
+
# module TestRepository
|
70
|
+
# extend DomainDrivenDesign::RepositoryBase
|
71
|
+
#
|
72
|
+
# entity_mapping id: id,
|
73
|
+
# name: :firstname
|
74
|
+
# end
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# @example With lambdas
|
78
|
+
# module TestFeature
|
79
|
+
# module TestRepository
|
80
|
+
# extend DomainDrivenDesign::RepositoryBase
|
81
|
+
#
|
82
|
+
# entity_mapping id: id,
|
83
|
+
# name: ->(data) { data.firstname + ' ' + data.lastname }
|
84
|
+
# end
|
85
|
+
# end
|
86
|
+
#
|
87
|
+
# @see #mapping_function
|
88
|
+
# @see #map_to_entity
|
89
|
+
#
|
90
|
+
# @overload entity_mapping(entity_mapping)
|
91
|
+
# Sets a value on key
|
92
|
+
# @param entity_mapping [Hash] mapping from entity attributes to data methods or callables
|
93
|
+
# @return [Hash]
|
94
|
+
# @overload entity_mapping
|
95
|
+
# Gets the entity mapping
|
96
|
+
# @return [Hash]
|
97
|
+
def entity_mapping(entity_mapping = nil)
|
98
|
+
return @entity_mapping unless entity_mapping
|
99
|
+
|
100
|
+
@entity_mapping = entity_mapping
|
101
|
+
end
|
102
|
+
|
103
|
+
# simple mapping helper which wraps a call to the given method name in a lambda
|
104
|
+
def mapping_function(sym)
|
105
|
+
->(data) { send sym, data }
|
106
|
+
end
|
107
|
+
|
108
|
+
# simple mapping helper which wraps a call to the given entity repository in a lambda
|
109
|
+
def map_to_entity(entity, rule)
|
110
|
+
->(data) { entity.repository.build_entity retrieve_value(rule, data) }
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
def map_arguments(mapping, data_object)
|
116
|
+
mapping.transform_values { |rule| retrieve_value(rule, data_object) }
|
117
|
+
end
|
118
|
+
|
119
|
+
def retrieve_value(rule, data)
|
120
|
+
if rule.is_a? Symbol
|
121
|
+
data.method(rule).call
|
122
|
+
elsif rule.respond_to? :call
|
123
|
+
rule.call data
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'team_fastlane/domain_driven_design/entity_base'
|
4
|
+
require 'team_fastlane/domain_driven_design/repository_base'
|
5
|
+
require 'team_fastlane/domain_driven_design/version'
|
6
|
+
|
7
|
+
module TeamFastlane
|
8
|
+
module DomainDrivenDesign
|
9
|
+
end
|
10
|
+
end
|
metadata
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: team_fastlane-domain_driven_design
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Team Fastlane
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-08-02 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email:
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files:
|
18
|
+
- README.adoc
|
19
|
+
- CHANGELOG.adoc
|
20
|
+
files:
|
21
|
+
- CHANGELOG.adoc
|
22
|
+
- README.adoc
|
23
|
+
- lib/team_fastlane/domain_driven_design.rb
|
24
|
+
- lib/team_fastlane/domain_driven_design/entity_base.rb
|
25
|
+
- lib/team_fastlane/domain_driven_design/repository_base.rb
|
26
|
+
- lib/team_fastlane/domain_driven_design/version.rb
|
27
|
+
homepage:
|
28
|
+
licenses:
|
29
|
+
- MIT
|
30
|
+
metadata:
|
31
|
+
rubygems_mfa_required: 'true'
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options: []
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.7'
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
requirements: []
|
47
|
+
rubygems_version: 3.4.10
|
48
|
+
signing_key:
|
49
|
+
specification_version: 4
|
50
|
+
summary: Gem for an internal project
|
51
|
+
test_files: []
|