Hacker News new | ask | show | jobs
by jshen 5313 days ago
My controllers are thin, but they do serve a purpose. They check if a user is logged in, authorized to view the thing they requested, check if I need to redirect for SEO purposes, prevent request forgery, redirecs if a form validation doesnt pass, and many other things.

Where does he do this stuff? I'm guessing much of it is done via ring middleware, but some of it doesn't fit there, and it doesn't fit in the view or model either.

4 comments

I agree with you - checking if a user is logged in, authorization, validating the request, choosing the right view to handle the response (html, json, csv, redirection if you just did a POST and so on), these all belong in a controller action. The framework can be smart about it, relying on conventions and all that, but if there's one thing I've learned is that the rules are meant to be broken and I never met a project that fit perfectly in the sweat-spot of any framework (which is why I do not think middleware cuts it for specific scenarios).

To me the rules are pretty clear:

   * data-processing stuff belongs in models
   * business-logic belongs in *business models*, 
     if said logic is related to the UI (i.e. repeat-password),
     although for simplicity you can choose not to bother
   * request processing (authorization, choosing the models, 
     choosing the view) belongs in a controller action
   * response processing belongs in a view
Regarding view forwarding, I once had a request that based on a parameter, instead of rendering HTML it would forward to a view that sent an email to the user with a CSV file attached, then redirected to a notification message. But only if the user was properly authorized. So the controller's logic was getting reused, forwarding to multiple views depending on expected output. Now that's a real controller and a real view.
user is logged in, authorized to view the thing they requested, check if I need to redirect for SEO purposes, prevent request forgery, redirecs if a form validation

And you can't do those things based on your framework in either, a general config of the app or a simple declarative manner, that fits into a simple function that decides which view to render, based on data?

Also shouldn't form validation be a mapping of data to your "domain objects" and let them decide if they're valid?

I think we're getting into semantics. I don't see the difference between "doing it in your framework" and "doing it in your controller" considering that my controller is part of my framework. I do a lot of rails and my controllers are mostly thin declarative setup of filters and such.

regarding validations, my models do decide if a from submission is valid, but the controller then decides what to do if the submission is invalid. I.e. serenader the form with some error messages. This is a good example of something that makes more sense to me in a controller.

I'm curious, how _do_ you code authorization and what not in Noir?
I don't much of a difference between a pre-route and a controller. If anything the controller seems better because I can more easily see the logic that will apply to a given request.
> some of it doesn't fit there, and it doesn't fit in the view or model either.

In Django, which does not have controllers either, you'd do this via a view decorator in the URL dispatcher: the URL dispatcher is essentially the "plugin point" for the framework-provided controller(s)

Hm? Django has controllers, they just call them views. And what Django calls templates are typically called views in other frameworks.
https://docs.djangoproject.com/en/dev/faq/general/#django-ap...

Django styles itself as MTV: Model Template View. The concept of "Controller" within Django I would say gets implemented across a few layers (Urls, middleware, decorators and return HttpResponse objects).

I never cared much for the distinction though as long as everyone knows what your nouns mean for the specific project you could call them RedFish, BlueFish, OneFish frameworks and it would work just as well.

I was always under the impression that in Django despite the fact that they are called "views" they're pretty much controllers. The view is really just the template.