Dry-rb for view-only Ruby on Rails microservice part 1

Dry-rb for view-only Ruby on Rails microservice part 1
Average rating: 0
(0 votes)

Thanks! You’ve rated this material!

catsThis is first tech post about different aspects of creating Ruby on Rails microservices. This microservice is a complex wizard form. It allows to fill the data in step-by-step wizard.

It works without any persistence layer, just passing the data through. Ruby on Rails microservice without database.

To work with forms without any database at the backend our first decision was using the ActiveModel. It helps us to create the models with a given set of fields, render it in the web form, send on a server, and validate. So, we needed some kind of Form Objects.

class Box
  include ActiveModel::Model

  cattr_reader :allowed_attributes do
    %i(packing clothes drawings)

    numericality: {
      only_integer: true,
      greater_than_or_equal_to: 0,
      less_than_or_equal_to: 100,
      allow_nil: true

While developing we find out that a Box should have a default parameters. For instance, zeros.  To make things working we used code like this.

Box.new(packing: 0, clothes: 0, drawings: 0)

There are 3 attributes only 🙂

After some time, the following code appeared in the app:

module MyCoolAttribute
  extend ActiveSupport::Concern

  module ClassMethods
    def init_all_with(value)
      opts = allowed_attributes.each_with_object({}) do |key, acc|
        acc = value


class Box
  include MyCoolAttribute

# usage
@box = Box.init_all_with(0)

Another way was using fabrics

class Box
  def self.new_with_defaults
    new(packing: 0, clothes: 0, drawings: 0)

It becomes boring 🙁

Fortunately there are plenty of alternatives to ActiveModel, so called attributes-on-steroids libraries. These are:

Now we use dry-types from the Dry-rb collection as the replacement of ActiveModel

# declaring types
module Types
  include Dry::Types.module

  ZeroBox = Int.optional.default(0)

class Box < Dry::Types::Struct
  # allows to not declare the whole set of options
  constructor_type :schema

  attribute :packing, Types::ZeroBox
  attribute :clothes, Types::ZeroBox
  attribute :drawings, Types::ZeroBox

# {:packing => 0, :clothes => 0, :drawings => 0}

That’s it!

P.S. dry-rb is the collection of the following small libraries, we will talk cover some of them in the future.

  • dry-validation Powerful data validation based on predicate logic
  • dry-types Flexible type system with many built-in types
  • dry-transaction Business transaction DSL
  • dry-container Simple and thread-safe IoC container
  • dry-auto_inject Container-agnostic constructor injection mixin
  • dry-equalizer Simple mixin providing equality methods
  • dry-component Organize your code into reusable components
  • dry-configurable Thread-safe configuration mixin
  • dry-logic Predicate logic with composable rules
  • dry-result_matcher Expressive match API for operating on Either results

part 2

Rate this article, if you like it

Thanks! You’ve rated this material!

Got a project? Let's discuss it!

    Kyiv Sofiivska 1/2a, 01001, Kyiv, Ukraine
    Dnipro Hlinky 2, of. 1003, 49000, Dnipro, Ukraine
    Kharkiv Otakara Yarosha 22, 61000, Kharkiv, Ukraine
    Email info@syndicode.com