-
Notifications
You must be signed in to change notification settings - Fork 9
/
solid-process-2.80.rb
78 lines (64 loc) · 2.15 KB
/
solid-process-2.80.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
class User::Registration < Solid::Process
deps do
attribute :mailer, default: UserMailer
attribute :repository, default: User::Repository
attribute :token_creation, default: User::Token::Creation
attribute :account_creation, default: Account::Member::OwnerCreation
validates :repository, respond_to: [:exists?, :create!]
end
input do
attribute :uuid, :string, default: -> { ::UUID.generate }
attribute :email, :string
attribute :password, :string
attribute :password_confirmation, :string
before_validation do
self.email = email.downcase.strip
end
with_options presence: true do
validates :uuid, format: ::UUID::REGEXP
validates :email, format: User::Email::REGEXP
validates :password, confirmation: true, length: {minimum: User::Password::MINIMUM_LENGTH}
end
end
def call(attributes)
rollback_on_failure {
Given(attributes)
.and_then(:check_if_email_is_taken)
.and_then(:create_user)
.and_then(:create_user_account)
.and_then(:create_user_token)
}
.and_then(:send_email_confirmation)
.and_expose(:user_registered, [:user])
end
private
def check_if_email_is_taken(email:, **)
input.errors.add(:email, "has already been taken") if deps.repository.exists?(email:)
input.errors.any? ? Failure(:invalid_input, input:) : Continue()
end
def create_user(uuid:, email:, password:, password_confirmation:, **)
case deps.repository.create!(uuid:, email:, password:, password_confirmation:)
in Solid::Success(user:) then Continue(user:)
in Solid::Failure(user:)
input.errors.merge!(user.errors)
Failure(:invalid_input, input:)
end
end
def create_user_account(user:, **)
case deps.account_creation.call(uuid: user.uuid)
in Solid::Success then Continue()
end
end
def create_user_token(user:, **)
case deps.token_creation.call(user:)
in Solid::Success then Continue()
end
end
def send_email_confirmation(user:, **)
deps.mailer.with(
user:,
token: user.generate_token_for(:email_confirmation)
).email_confirmation.deliver_later
Continue()
end
end