DEV Community

loading...
Cover image for Dependency Injection in Ruby 🌈

Injection Ruby Dependency Injection in Ruby 🌈

eligoh profile image Elijah Goh ・2 min read

I once wrote an article on Medium about dependency injection - Dependency Injection is not Scary!. Recently joined dev.to, I thought I'd bring my thoughts here as well.

Okay Eli, I know how to dependency inject now thanks to the medium article. BUT WHEN DO USE IT?

Bear with me here, I'll get to that soon. Currently building an inbox feature, I needed a form object for creating the conversation AND responding/editing the conversation.

What I could have done was create a form object, wipe my hands clean and be done with it. Or I could also make this form reusable in other controllers. πŸ€“

module Inbox
  class ConversationForm < BaseForm
    attr_reader :conversation, :message, :sender

    def initialize(conversation, params = {})
      @conversation = conversation
      @sender = build_sender
      @message = conversation.messages.build(user: @sender)
    end

    ...
  end
end
Enter fullscreen mode Exit fullscreen mode

But making use of dependency injection, I was able to reuse the form for another controller.

module Inbox
  class ConversationForm < BaseForm
    attr_reader :conversation, :message, :sender

    def self.build(params={})
      conversation = Conversation.new
      sender = build_sender
      new(conversation, sender, params)
    end

    def initialize(conversation, sender, params = {})
      @conversation = conversation
      @sender = sender
      @message = converation.messages.build(sender: sender)
    end

    ...
  end
end
Enter fullscreen mode Exit fullscreen mode

I would use Inbox::ConversationForm.build when I want to create a new conversation. In another controller/action, I would predefine the conversation and inject it into the form.

# ConversationsController
# Creating a Conversation
def new
  @form = Inbox::ConversationForm.build
end

# My::ConversationsController
def new
  @form = Inbox::ConversationForm.new(fetch_conversation, Current.user)
end

# BOTH
def create/update
  if @form.save
    render :new
  else
    redirect_to some_path
  end
end

private

def fetch_conversation
  Inbox::Conversation.find(params[:conversation_id])
end
Enter fullscreen mode Exit fullscreen mode

Once again, go forth and Dependency Inject!

Discussion

pic
Editor guide