-
Notifications
You must be signed in to change notification settings - Fork 9
/
solid-process-2.00.rb
82 lines (64 loc) · 2.09 KB
/
solid-process-2.00.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
79
80
81
82
class User::Registration < Solid::Process
deps do
attribute :mailer, default: UserMailer
attribute :token_creation, default: User::Token::Creation
attribute :task_list_creation, default: Account::Task::List::Creation
end
input do
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 :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_inbox)
.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 User.exists?(email:)
input.errors.any? ? Failure(:invalid_input, input:) : Continue()
end
def create_user(email:, password:, password_confirmation:, **)
user = User.create(email:, password:, password_confirmation:)
return Continue(user:) if user.persisted?
input.errors.merge!(user.errors)
Failure(:invalid_input, input:)
end
def create_user_account(user:, **)
account = Account.create!(uuid: SecureRandom.uuid)
account.memberships.create!(user:, role: :owner)
Continue(account:)
end
def create_user_inbox(account:, **)
case deps.task_list_creation.call(account:, inbox: true)
in Solid::Success(task_list:) then Continue()
end
end
def create_user_token(user:, **)
case deps.token_creation.call(user:)
in Solid::Success(token:) 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