Closed jobertabma closed 11 years ago
Hey Jobert, could we maybe split this up over several issues? I think, that way we can discuss it easier. I have some answers/opinions on some points, but I'm afraid that if we do this in one issue it won't be very usable.
Maybe @markijbema could also preemptively close this issue, so it's clear we're not going to do anything in this issue.
Last week I spent time on Pavlov's code. I looked at the way Pavlov was structured and how it is used. Did a small write-up about this:
Unit tests A while ago I noticed that the
authorized?
andvalidate
methods cannot be unit tested. This is due to the fact that the initializer of the interactor calls theauthorized?
andvalidate
method. Right now, unit tests of theauthorized?
methods look like this:The problem here is that it doesn't test the
authorized?
method itself. ThePavlov::AccessDenied
exception could also be raised by thehas_access?
method which is implemented in a lot of interactors. A better way of testing these methods would be something like:Optional arguments Every once in a while developers want to write a query, interactor or command that can take an optional argument. Right now this is not possible. Optional arguments are typically implemented like this:
A cleaner way to do this would be something like this:
In this example the
arg
method takes a symbol that looks for the:optional_argument
argument. If it is not found, the second parameter is returned (in this casefalse
). Retrieving arguments would also clean user's code base, because they are not bound to a specific order of the arguments anymore. A structure below might make more sense because of its backwards compatibility with the current Pavlov though:Code duplication The interactors take an optional options hash. This hash includes additional arguments that can be passed to an interactor. In most cases this hash contains the
current_user
key. The value of this key contains aUser
object and is used for doing authentication and authorization checks. Calling an interactor currently looks something like this:The third argument are referred to as the 'Pavlov options'. Looking at the way it is used, it is just an argument for the interactor. Given the fact that it is passed through to the interactors in all situations, the arguments could be merged. This would look something like this:
The
interactor
method merges thePavlov::options
hash and hash that is given to the second parameter of theinteractor
method. A side-effect of looking at it this way is that thecurrent_user
becomes an argument of an interactor (instead of it being a 'special' option).Inconsistent naming Pavlov has some inconsistent method names. An interactor only contains an
authorized?
method. This method is typically used for an authentication check. Thehas_access?
method is typically used for implementing the authorization check. The problem is that thehas_access?
method needs to be called manually in theexecute
method`. It looks something like this:People end up testing if the
has_access?
method is called in theexecute
method (which is called manually). It'd be better to separate this logic and rename the methods. I'd propose something like this:The ActiveSupport dependency Currently, Pavlov depends on ActiveSupport inflectors:
The
constantize
andcamelize
methods are part of ActiveSupport. In terms of decoupling and stop depending on these kind of frameworks, I'd propose to replace these calls using the following code:Obsolete code Looking at the code base it seems that the commands and queries also have an
authorized?
method. Given the fact that Pavlov's philosophy is partially about centralizing logic into interactors, it doesn't seem like this is the way to go. I'd propose to remove this functionality.Wanted to start a discussion about these topics – will try to come up with a couple of smaller pull requests to implement the topics above. Let me know what you think!