Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A New Ruby Toolbox

Jojo
November 02, 2017

A New Ruby Toolbox

dry-rb and rom-rb are libraries for Rubyists who are looking for a different set of tools for web app development. Let’s take a walk through how to build an app with these families of gems, and look at some lessons I’ve learnt during my own dry-rb/rom-rb journey.

Jojo

November 02, 2017
Tweet

Other Decks in Programming

Transcript

  1. !

  2. class Index < Dry::View::Controller configure do |config| config.paths = [File.join(__dir__,

    "templates")] config.layout = "app" config.template = "index" end expose :products end
  3. class Index < Dry::View::Controller configure do |config| config.paths = [File.join(__dir__,

    "templates")] config.layout = "app" config.template = "index" end expose :products end
  4. class Index < Dry::View::Controller configure do |config| config.paths = [File.join(__dir__,

    "templates")] config.layout = "app" config.template = "index" end expose :products end
  5. class Index < Dry::View::Controller configure do |config| config.paths = [File.join(__dir__,

    "templates")] config.layout = "app" config.template = "index" end expose :products end
  6. class Index < Dry::View::Controller configure do |config| config.paths = [File.join(__dir__,

    "templates")] config.layout = "app" config.template = "index" end expose :products end
  7. class Index < Dry::View::Controller configure do |config| config.paths = [File.join(__dir__,

    "templates")] config.layout = "app" config.template = "index" end expose :products end
  8. module App class ViewController < Dry::View::Controller configure do |config| config.paths

    = [File.join(__dir__, "templates")] config.layout = "app" end end end
  9. module App class ViewController < Dry::View::Controller configure do |config| config.paths

    = [File.join(__dir__, "templates")] config.layout = "app" end end end
  10. route "products" do |r| r.post do r.resolve "products.create" do |create|

    create.(r[:product]) do |m| m.success do r.redirect "/success" end m.failure do |result| r.view "error", error: result end end end end end
  11. route "products" do |r| r.post do r.resolve "products.create" do |create|

    create.(r[:product]) do |m| m.success do r.redirect "/success" end m.failure do |result| r.view "error", error: result end end end end end
  12. route "products" do |r| r.post do r.resolve "products.create" do |create|

    create.(r[:product]) do |m| m.success do r.redirect "/success" end m.failure do |result| r.view "error", error: result end end end end end
  13. route "products" do |r| r.post do r.resolve "products.create" do |create|

    create.(r[:product]) do |m| m.success do r.redirect "/success" end m.failure do |result| r.view "error", error: result end end end end end
  14. route "products" do |r| r.post do r.resolve "products.create" do |create|

    create.(r[:product]) do |m| m.success do r.redirect "/success" end m.failure do |result| r.view "error", error: result end end end end end
  15. route "products" do |r| r.post do r.resolve "products.create" do |create|

    create.(r[:product]) do |m| m.success do r.redirect "/success" end m.failure do |result| r.view "error", error: result end end end end end
  16. class Create < App::Operation include App::Import["product_repo"] def call(input) if valid?

    product = product_repo.create(input) Right(product) else Left("Invalid input”) end end end
  17. route "products" do |r| r.post do r.resolve "products.create" do |create|

    create.(r[:product]) do |m| m.success do r.redirect "/success" end m.failure do |result| r.view "error", error: result end end end end end
  18. result = schema.( 'title' => 'A Lion in the Meadow’,

    'published_at' => '1995-05-25', 'stock_level' => '' ) puts result.to_h { :title=>"A Lion in the Meadow", :published_at=>#<Date: 1995-05-25>, :stock_level=>nil }
  19. result = schema.( 'title' => 'A Lion in the Meadow’,

    'published_at' => '1995-05-25', 'stock_level' => '' ) puts result.to_h { :title=>"A Lion in the Meadow", :published_at=>#<Date: 1995-05-25>, :stock_level=>nil }
  20. result = schema.( 'title' => '', 'published_at' => '', 'stock_level'

    => '0' ) puts result.errors { :title=>["must be filled"], :published_at=>["must be filled"], :stock_level=>["must be greater than 1"] }
  21. result = schema.( 'title' => '', 'published_at' => '', 'stock_level'

    => '0' ) puts result.errors { :title=>["must be filled"], :published_at=>["must be filled"], :stock_level=>["must be greater than 1"] }
  22. class Create < App::Operation include App::Import["product_repo"] def call(input) validation =

    schema.(input) if validation.success? product = product_repo.create(validation.to_h) Right(product) else Left(validation) end end end
  23. class Create < App::Operation include App::Import["product_repo"] def call(input) validation =

    schema.(input) if validation.success? product = product_repo.create(validation.to_h) Right(product) else Left(validation) end end end
  24. class Create < App::Operation include App::Import["product_repo"] def call(input) validation =

    schema.(input) if validation.success? product = product_repo.create(input) Right(product) else Left(validation) end end end
  25. products_repo.create( title: "Where the Wild Things Are", published_at: #<Date: 1963-04-09>,

    stock_level: 4 )
 => #<ROM::Struct[Product] id=1 title="Where the Wild Things Are" published_at=#<Date: 1963-04-09> stock_level=4>
  26. products_repo.create( title: "Where the Wild Things Are", published_at: #<Date: 1963-04-09>,

    stock_level: 4 )
 => #<ROM::Struct[Product] id=1 title="Where the Wild Things Are" published_at=#<Date: 1963-04-09> stock_level=4>
  27. products_repo.update( product.id, title: "Wild Things" ) => #<ROM::Struct[Product] id=1 name="Wild

    Things" published_at=#<Date: 1963-04-09> stock_level=4> products_repo.delete(product.id)
  28. products_repo.update( product.id, title: "Wild Things" ) => #<ROM::Struct[Product] id=1 name="Wild

    Things" published_at=#<Date: 1963-04-09> stock_level=4> products_repo.delete(product.id)
  29. products_repo.update( product.id, title: "Wild Things" ) => #<ROM::Struct[Product] id=1 name="Wild

    Things" published_at=#<Date: 1963-04-09> stock_level=4> products_repo.delete(product.id)
  30. &

  31. &

  32. App::Transactions.define do |t| t.define "transactions.create_product" do step :create, with: "products.operations.create"

    enqueue :index, with: "search.operations.index_product" enqueue :notify, with: "products.operations.notify" end end
  33. App::Transactions.define do |t| t.define "transactions.create_product" do step :create, with: "products.operations.create"

    enqueue :index, with: "search.operations.index_product" enqueue :notify, with: "products.operations.notify" end end
  34. App::Transactions.define do |t| t.define "transactions.create_product" do step :create, with: "products.operations.create"

    enqueue :index, with: "search.operations.index_product" enqueue :notify, with: "products.operations.notify" end end
  35. App::Transactions.define do |t| t.define "transactions.create_product" do step :create, with: "products.operations.create"

    enqueue :index, with: "search.operations.index_product" enqueue :notify, with: "products.operations.notify" end end