collectiveidea / interactor

Interactor provides a common interface for performing complex user interactions.
MIT License
3.36k stars 212 forks source link

Custom context classes #145

Open bobbytables opened 7 years ago

bobbytables commented 7 years ago

I would love to see the ability to define custom Context classes as long as they implement the proper methods (Similar to ActiveModel linting).

Reason being is that OpenStruct leaves a lot of room for error, and have a proper domain object for context would alleviate a lot of that. For example, it would be really nice to be able to do:

class AuthenticateUser
  include Interactor
  context_class AuthenticateUserContext

  def call; end
end

class AuthenticateUserContext < Interactor::BaseContext
  attr_accessor :email, :password
end

Explanation of what this example is doing:

Interactor::BaseContext would implement all of the necessary internals of a context, for example fail! and rollback!.

But since it doesn't include OpenStruct, the only values that can be set are email and password due to the attr_accessor in the custom context class.

I like this because it makes you think of your design more coherently and actually gives more options at the end of an interactor call. For example, errors:

class AuthenticateUserContext < Interactor::BaseContext
  attr_accessor :email, :password

  def formatted_errors
    errors.map {|error_key| I18n.translate(error_key) }
  end
end
taylorthurlow commented 4 years ago

This certainly isn't a direct solution to your feature request (and you posted this 3 years ago 🤷), but with the lack of communication from the project maintainers, I forked Interactor. I'm making some pretty significant changes, but specifically you might like the more strict concept of interactor attributes rather than having a special context: https://github.com/taylorthurlow/interaktor