10. class User < ApplicationRecord
before_save :set_name
def set_name
self.name = [first_name, last_name].join(' ')
end
end
10/131
11. class User < ApplicationRecord
before_save :set_name, unless: -> u { u.source == 'github' }
def set_name
self.name = [first_name, last_name].join(' ')
end
end
11/131
18. def create
create_user = proc do |params|
name = params.values_at(:first_name, :last_name).join(' ')
User.create(params.merge(name: name))
end
user = create_user.call(params)
end
18/131
19. def create
user = create_user.call(params)
end
def create_user
delimiter = ' '
proc do |params|
name = params.values_at(:first_name, :last_name).join(delimiter)
User.create(params.merge(name: name))
end
end
19/131
73. class CreateUser
attr_reader :user_repo
def initialize
@user_repo = Shop::Container.resolve(:user_repo)
end
# ...
def create_from_data(data)
user_repo.create(data)
end
end
73/131
80. Shop::Container.namespace(:operations) do
register(:create_user) do
Shop::Operations::CreateUser.new
end
register(:create_post) do
Shop::Operations::CreatePost.new
end
register(:create_tag) do
Shop::Operations::CreateTag.new
end
register(:create_account) do
Shop::Operations::CreateAccount.new
end
register(:update_user) do
Shop::Operations::UpdateUser.new
end
register(:update_post) do
Shop::Operations::UpdatePost.new
end
register(:update_tag) do
Shop::Operations::UpdateTag.new
end
register(:update_account) do
Shop::Operations::UpdateAccount.new
end
end
80/131
82. dry-system
module Shop
class Container < Dry::Web::Container
configure do
config.auto_register = 'lib'.freeze
config.system_dir = 'system'.freeze
config.root = Pathname(__FILE__).dirname.join('../..')
end
load_paths! 'lib' # Adds to $LOAD_PATH
end
end
82/131
91. dry-monads
def call(input)
validation = Schema.(input)
if validation.success?
user = repo.create(validation.output)
Right(user)
else
Left(validation)
end
end
91/131
93. dry-matcher
class CreateUser
include Dry::Matcher.for(:call, with: Dry::Matcher::EitherMatcher)
def call(input)
validation = Schema.(input)
if validation.success?
user = repo.create(validation.output)
Right(user)
else
Left(validation)
end
end
end
93/131
94. dry-matcher
r.post do
r.resolve 'operations.create_user' do |create|
create.(r.params['user']) do |m|
m.success do |user|
r.redirect_to "/users/#{ user.id }"
end
m.failure do |validation|
# render errors
end
end
end
end
94/131
96. dry-view
r.post do
r.resolve 'operations.create_user' do |create|
create.(r.params['user']) do |m|
m.success do |user|
r.redirect_to "/users/#{ user.id }"
end
m.failure do |validation|
r.view 'users.new', validation: validation
end
end
end
end
96/131
97. dry-view
module Views
module Users
class New < Shop::ViewController
configure do |config|
config.template = "users/new"
end
expose :validation
end
end
end
97/131
101. dry-transaction
class CreateUser
Transaction = Dry::Transaction(container: Shop::Container) do
step :validate, with: 'operations.validate'
step :persist, with: 'persistance.commands.create_user'
end
end
101/131
102. dry-transaction
class CreateUser
Transaction = Dry::Transaction(container: Shop::Container) do
step :validate, with: 'operations.validate'
step :persist, with: 'persistance.commands.create_user'
end
def call(input, &block)
Transaction.(input, validate: [Schema], &block)
end
end
102/131
103. dry-transaction
class CreateUser
Transaction = Dry::Transaction(container: Shop::Container) do
step :validate, with: 'operations.validate'
step :persist, with: 'persistance.commands.create_user'
end
def call(input, &block)
Transaction.(input, validate: [Schema], &block)
end ^^^^^^^^^^^^^^^^^^
end
103/131
108. dry-struct
User.new(name: nil, email: 'john@doe.com', age: 33)
# => Dry::Struct::Error: [User.new]
# nil (NilClass) has invalid type for :name
108/131
109. dry-struct
class User < Dry::Struct
Name = Types::Strict::String
attribute :name, Name
attribute :email, Types::Strict::String
attribute :age, Types::Strict::Int
end
109/131