Skip to content

Instantly share code, notes, and snippets.

@manojmj92
Last active February 24, 2020 23:08
Show Gist options
  • Save manojmj92/02043ba9a0cfbb0854942e7b529e6461 to your computer and use it in GitHub Desktop.
Save manojmj92/02043ba9a0cfbb0854942e7b529e6461 to your computer and use it in GitHub Desktop.
# Definition of a BaseInteractor
class BaseInteractor
include Interactor
include ActiveModel::Validations
# For any class that inherits this class, a `before` hook is registered, which raises ArgumentError if the reqired parameters are not passed in during invocation.
def self.inherited(subclass)
subclass.class_eval do
def self.requires(*attributes)
validates_each attributes do |record, attr_name, value| #from ActiveModel::Validations
if value.nil?
raise ArgumentError.new("Required attribute #{attr_name} is missing")
end
end
delegate *attributes, to: :context
end
before do
context.fail!(errors: errors) unless valid? # runs every validation
end
def read_attribute_for_validation(method_name)
context.public_send(method_name)
end
end
end
end
# Definition of the Interactor using the BaseInteractor
class MyInteractor < BaseInteractor
requires :email, :name
validate :email_is_internal
def call
# ...
end
private
def email_is_internal
return unless email.present?
errors.add(:email, 'domain should be reflektive.com') unless context.email.match(/^[a-z]+.\@reflektive\.com$/i)
end
end
# Invocation of the Interactor
result = MyInteractor.call(email: '[email protected]')
# => ArgumentError: Required parameter name is missing.
result = MyInteractor.call(email: '[email protected]', name: 'Bob')
result.success? # => false
puts result.errors # => ['email domain should be reflektive.com']
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment