5 examples of Ruby’s best usage
Have you ever wondered what we can do with Ruby? Well, the sky is probably the limit, but we are happy to talk about some more or less known cases...
Pub/Sub can bring many benefits to the project – it can make the code clean, decouple services and make them easily scalable. Learn more about Pub/Sub in the following article and level up your project!
Ruby on Rails (Rails, RoR) is a well-known web application framework written in the Ruby programming language. Pub/Sub is a short name of software design patterns called Publish–subscribe. I’ll explain how communication between software components in Rails could be handled by Pub/Sub.
Pub/sub is a software design pattern providing service-to-service communication. Service
entails one of the two roles: publisher (who produce) or receiver (who consumes). What is
produced to be consumed is determined as an event or a message or a notification. In the
context of this article, they are used interchangeably to refer to the same thing.
The service which produces doesn’t know who consumes. The service which consumes doesn’t
know the origin of the message. They can remain unknown to each other. It is different from
message queues, where the component that sends the message often knows its destination
– this style of messaging allows you to send messages anywhere. This mechanism is a core
of Pub/sub and it means that they are decoupled.
To express their mutual interests, they must share a common understanding. Therefore,
both roles have an implicit mechanism of the stick where the producer of a message and the
consumer of the message meet. This mechanism is called subject, subscription or topic. It is
responsible for categorizing messages to subjects, it is essentially a stateless message filter.
Topics act as broadcast stations. A publisher produces the message to the topic,
subscribers immediately receive the message from the topic. Because of decoupled
services, the most efficient way of exchanging messages is to handle them asynchronously.
By default, there is no Rails overhead for software design patterns for passing messages between components. Developers use standard object-oriented programming (OOP) paradigm: passing parameters to functions, asking for classes about values.
When the application is rather uncomplicated, it could be enough. When the application grows, for instance, some operations need to be done asynchronously, then the project needs abstraction which resolves that data workflow. Instead of reinventing the wheel, developers can implement Pub/sub to fill this lack of abstraction.
Examples of source in Rails was written using library
Pub/Sub on Rails (in Ruby’s nomenclature, a library is called gem): You will find more details in the gem’s readme. Implementation is composed of modules:
Describes business logic in order to provide context for Pub/Sub and, therefore, make clean code.
module Notifications
extend PubSub::Domain
end
module Reports
extend PubSub::Domain
end
It is a class which describes what happened. Declare the class name as self-describing with what happened as possible, for example: cancelled, changed, created, destroyed, sent, updated. Event names can look like: ProfitAndLossStatementCreatedEvent, which means that a financial statement was created.
class Reports::ProfitAndLossStatementCreatedEvent < PubSub::DomainEvent
attribute :profit_and_loss_statement_id, Types::Strict::Integer
end
Class capable of emitting events. The example shows creating a service report. When the report was successfully created, emit the event of creating that report.
class Reports::ProfitAndLossStatementService
include PubSub::Emit
def execute
emit(:report_profit_and_loss_statement_created, profit_and_loss_statement_id: id) if result.ok?
end
end
This class should be executed in response to handling an event.
module Notifications
class ReportsProfitAndLossStatementCreatedHandler < PubSub::DomainEventHandler
def call
ReportMailer.profit_and_loss_statement(profit_and_loss_statement).deliver_now
end
private
def profit_and_loss_statement
ProfitAndLossStatement.find(event_data.profit_and_loss_statement_id)
end
end
end
Events are bonded to their handlers through subscriptions.
notifications:
reports__profit_and_loss_statement_created: async
Pub/sub is not a common approach in Ruby in Rails. As introduced in the article, this pattern can bring many benefits to the project – it can make the code clean, decouple services and make them easily scalable.