No?
It provides some very marginal improvement, but doesn't address the actual problem of the code, which is the horrific verbosity. The use of attributes is the least of my problem with it. This is how I'd want it to look:
class UserCreator
# Arguably, I'd prefer *call* because that allows it to be interchangeable with a lambda
# But frankly this thing could *be* a lambda. E.g. you could replace the above class declaration
# with "UserCreator = ->(email) do" and ditch the "def"
# The exception, where I'd allow for an initialize and attributes would be in cases where you'd otherwise
# be passing a *lot* of *the same* state around between multiple methods
#
def self.create_user(email)
User.create(email).tap do |user|
user.roles << Roles.find_by(name: 'admin')
user.permissions << Permissions.find_by(name: 'invite')
Templates.find_by(name: 'invite').call(user: user)
end
end
end
The whole service object pattern is heavily abused by people who don't seem to understand which (limited) situations it actually provides benefits. This isn't one of them.