Normally I expect that once an object is constructed, it should be ready for use, period. No two step construction. If you need calling two constructors for using an object something is very wrong... right?
class Contact
attr_accessor :auth_token
def initialize(contact_hash)
...
end
def edit(...)
auth_token.can! :read, self
end
end
token = AuthorizationToken.new(session)
contact = SomeService.get_contact(...)
contact.edit(...)
# raise error because auth_token is not set
contact.auth_token = token
contact.edit(...)
The code above represents my current dilemma: I want SomeService to give me Contact objects, but I do not want that service to be concerned about an existing session, or authorization at all.
My current approach is adding this extra class:
class QueryService
def initialize(session)
token = AuthorizationToken(session)
end
def get_contact
contact = SomeService.get_contact(...)
contact.token = token
end
end
contact = QueryService.new(session).get_contact(...)
contact.edit(...)
This solution gives me the most freedom to use authorization concerns inside the core domain object Contact, implement them in an external class AuthorizationToken and implement services that are not concerned about the current user session SomeService.
However the two step construction is killing me. It feels strange: An object that is not fully initialized for some operations???
This is not a plain case of dependency injection, but more exactly a context injection. So most of the articles about avoiding DI in Ruby do not really solve my problem. I am wondering if there is a more Ruby way to solve this, or this is just as clean as it can get.