All Projects → guideline-tech → subroutine

guideline-tech / subroutine

Licence: MIT license
Subroutine makes it easy to write encapsulated, feature-driven code. It handles the boilerplate of inputs, outputs, type casting, and validation and lets you focus on the important functional code.

Programming Languages

ruby
36898 projects - #4 most used programming language

Projects that are alternatives of or similar to subroutine

Java-Programs
Java Practiced Problems including concepts of OOPS, Interface, String , Collection.
Stars: ✭ 51 (+50%)
Mutual labels:  encapsulation
performify
Service object which makes you better.
Stars: ✭ 14 (-58.82%)
Mutual labels:  service-objects
ipdecap
Decapsulate traffic encapsulated within GRE, IPIP, 6in4, ESP (ipsec) protocols, can also remove IEEE 802.1Q (virtual lan) header. Works with pcap files.
Stars: ✭ 32 (-5.88%)
Mutual labels:  encapsulation
Redes
High-level network layer abstraction library written in Swift.
Stars: ✭ 16 (-52.94%)
Mutual labels:  encapsulation
blanket
Soft encapsulation for Clojure data structures
Stars: ✭ 22 (-35.29%)
Mutual labels:  encapsulation
from-fat-controllers-to-use-cases
Rails (API) app that shows different kinds of architecture (one per commit), and in the last one, how to use the Micro::Case gem to handle the application business logic.
Stars: ✭ 74 (+117.65%)
Mutual labels:  service-objects

Subroutine

A gem that provides an interface for creating feature-driven operations. You've probably heard at least one of these terms: "service objects", "form objects", "intentions", or "commands". Subroutine calls these "ops" and really it's just about enabling clear, concise, testable, and meaningful code.

Example

So you need to sign up a user? or maybe update one's account? or change a password? or maybe you need to sign up a business along with a user, associate them, send an email, and queue a worker in a single request? Not a problem, create an op for any of these use cases. Here's the signup example.

class SignupOp < ::Subroutine::Op

  string :name
  string :email
  string :password

  string :company_name

  validates :name, presence: true
  validates :email, presence: true
  validates :password, presence: true
  validates :company_name, presence: true

  outputs :user
  outputs :business

  protected

  def perform
    u = create_user!
    b = create_business!(u)

    deliver_welcome_email(u)

    output :user, u
    output :business, b
  end

  def create_user!
    User.create!(name: name, email: email, password: password)
  end

  def create_business!(owner)
    Business.create!(company_name: company_name, owner: owner)
   end

  def deliver_welcome_email(u)
    UserMailer.welcome(u.id).deliver_later
  end
end

So why use this?

  • Avoid cluttering models or controllers with logic only applicable to one intention. You also don't need strong parameters because the inputs to the Op are well-defined.
  • Test the Op in isolation
  • Clear and concise intention in a single file
  • Multi-model operations become simple

Continue Reading

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].