facebook Clutch Top custom software development companies

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)
  end

  validates(*allowed_attributes,
    numericality: {
      only_integer: true,
      greater_than_or_equal_to: 0,
      less_than_or_equal_to: 100,
      allow_nil: true
    })
end

 

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
      end

      new(opts)
    end
  end
end

class Box
  include MyCoolAttribute
end

# 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)
  end
end

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)
end

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
end

Box.new.to_h
# {: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!

*By submitting this form you agree with our Privacy Policy.

Mailing & Legal Address

Syndicode Inc. 340 S Lemon Ave #3299, Walnut CA, 91789, USA

Visiting & Headquarters address
Kyiv Sofiivska 1/2a, 01001, Kyiv, Ukraine
Dnipro Hlinky 2, of. 1003, 49000, Dnipro, Ukraine
Email info@syndicode.com
Phone (+1) 9035021111