Validate params
Update existing user record
Send verification email
Return result to user
def update_user_email(params)
user.find(params[:user_id])
user.update_attributes(email: params[:user_email])
UserMailer.send_email_changed_email(user)
end
def update_user_email(params)
user.find_by_id(params[:user_id])
if user
user.update_attributes(email: params[:user_email])
UserMailer.send_email_changed_email(user)
else
:user_not_found
end
end
def update_user_email(params)
user.find_by_id(params[:user_id])
if user
if user.update_attributes(email: params[:user_email])
UserMailer.send_email_changed_email(user)
else
user.errors.message
end
else
:user_not_found
end
end
def update_user_id(params)
user.find_by_email(params[:user_id])
if user
if user.update_attributes(email: params[:user_email])
UserMailer.send_email_changed_email(user)
catch ResqueFailed
:resque_failed
else
user.errors.message
end
else
:user_not_found
end
end
def step_implementation(input)
return Failure(:error) if input.valid?
Success(input)
end
require "dry/transaction"
class UpdateUser
include Dry::Transaction
step :validate
step :save
step :send_user_update_email
private
def validate(input)
# returns Success(valid_data) or Failure(validation)
end
def save(input)
# returns Success(user)
end
#...
end
create_user = UpdateUser.new
create_user.call(email: 'test@email.com') do |m|
m.success do |user|
puts "Updated user email to #{user[:email]}"
end
# You can match exact steps, only the first match is executed
m.failure :validate do |validation|
puts validation
puts 'Invalid params for user'
end
m.failure do |error|
puts "Sorry but #{error} stopped us"
end
end
class UpdateUser
include Dry::Transaction(container: ::Container)
step :validate, with: "validate_user_params"
step :save, with: "save_user"
step :send_user_update_email, with: "send_user_update_email"
end
You can use dry-container for this(optional)
class UpdateUser
include Dry::Transaction(container: ::Container)
step :validate, with: "validate_user_params"
step :save, with: "save_user"
step :send_user_update_email, with: "send_user_update_email"
private
def validate(input)
adjusted_input = upcase_values(input)
end
def upcase_values(input)
#...
end
end
You can use dry-container for this(optional)
def validate(input)
schema = Dry::Validation.Schema do
required(:email).filled(:str?)
end
schema.call(input).to_monad
end
(optional) You can also use dry-validation, theres monads extension to make it seamless
NOTIFICATIONS = []
module UserCreationListener
extend self
def on_step(event)
NOTIFICATIONS << "Started creation of #{user[:email]}"
end
end
create_user = CreateUser.new
create_user.subscribe(create: UserCreationListener)
create_user.call(name: "joe", email: "joe@doe.com")
NOTIFICATIONS
# => ["Started creation of joe@doe.com"]
class TransferProject
include Dry::Transaction
step :fetch_project # Returns Success(output) or Failure(:project_not_found)
step :fetch_user
check :owner_can_release_ownership? # Returns true/false
check :user_can_own_project? # Returns true/false
step :transfer_project_ownership # Returns Success(input) or Failure(:project_transfer_error)
step :notify_user # Returns Success(input) or Failure(:cannot_notify_user)
end
include Dry::Transaction
around :transaction
#...
def transaction(input, &block)
puts '#### Transaction START ####'
result = block.(Success(input))
puts '#### Transaction END ####'
result
# transaction do
rescue TransactionError
Failure(:db_error)
end
#### Transaction START ####
Transfered the project to Joe Doe
Notified user Joe Doe
#### Transaction END
transfered the project
You get a cookie for each question