Skip to content

Instantly share code, notes, and snippets.

@paulcsmith
Last active July 1, 2020 20:44
Show Gist options
  • Save paulcsmith/3ce36672c5122b7cc9ca437b74b66e82 to your computer and use it in GitHub Desktop.
Save paulcsmith/3ce36672c5122b7cc9ca437b74b66e82 to your computer and use it in GitHub Desktop.
New and improved operations
class User
# Horrible name, but basically adds these validations that should always run
validations_that_always_run do
validate_email(email)
validate_size_of age, min: 13
end
end
module Users::PasswordAttributesAndValidations
macro included
attribute password : String
attribute password_confirmation : String
validate do
validate_confirmation_of password, with: password_confirmation
validate_size_of password, min: 8
end
end
end
class Users::SignUp < User::SaveOperation
# Shared between SignUp and UpdatePassword operations
include PasswordAttributesAndValidations
only_create # Makes it so you call `run!/run` directly and raises compile error if calling `create/update`
permit_columns :name, :age, :email # This remains the same as today
attribute terms_of_service : Bool # Remains the same.
needs current_user : User # Remains the same
# Introduce a new `validate` stack separate from `before_save`.
# Also needs `before_validate` to prepare data before validation. Exact details TBD
validate do
# No need to do the age and email validations. Handled by defaults set in the model!
# So just to Sign Up specific stuff
validate_acceptance_of terms_of_service
end
after_commit do |user|
send_confirmation_email
end
end
# New way of naming so similar operations can be found in one folder. Use namespace of model
# Also means you could technically do `UpdatePassword.run!` inside `Users::Passwords::Update` since they are in the same namespace
class Users::UpdatePassword < User::SaveOperation
include PasswordAttributesAndValidations
only_update
end
## Param customization
class Users::SignUp < User::SaveOperation
# get params from the root key. Many APIs prefer this
root_params do
permit_columns :name, :age, :email # `params.get(:name)` instead of `params.get(:
attribute search_term : String, param_key: :q # Would do `params.get(:q)` instead of `:search_term`
end
# or rename the key it is nested under.
param_key :user do
permit_columns :name, :age, :email
attribute password : String
end
# You can mix and match if you want. Like doing some in a param_key and some under a root param key
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment