I was posting “a stupid simple example how Cells can be used”:http://nicksda.apotomo.de/2010/10/why-rails-controllers-need-a-double-render/ the other day. This controversial post got lots of great comments, thanks to all! While some just questioned Cells and its use, a few *comments really bashed the project* in a very aggressive way. *I like that.*
The rudeness in some sequential comments seems to come from one cause: *Ignorance.* The writings simple proof that the author did *not understand anything about Cells, and MVC in Rails*.
I’ll pick some points from different authors and try to explain.
* “It messes MVC up.”
* “a place that also breaks the MVC framework.”
* “Not only are you abstracting view code out to a place where it simply doesn’t belong, …”
* “I’m not convinced that the benefits of Cells outweigh the complexity they add.”
* “I think you are a nut.”
h3. MVC and Rails
Ok, I won’t explain MVC here again. We already got “great writings about that”:http://martinfowler.com/eaaDev/uiArchs.html – however, there are two points in Rails’ MVC design that might cause confusion.
* The ActionController mixes MVC and the “FrontController”:http://martinfowler.com/eaaCatalog/frontController.html , and this creates the impression that web apps have to be one monolithic controller, one view, and maybe a couple of partials rendered in the controller context.
* *Rails hides rendering*, so in most cases the programmer doesn’t realize templates rendering happens “in” the controller.
Cells are small controllers, derived from @AbstractController@. You can imagine them as *small, separate MVC-stacks between the traditional Rails VC-layer*. There is nothing wrong with that, right, Martin?
At this point I should stress that there’s not just one view and controller, you have a view-controller pair for each element of the screen
(Martin Fowler about MVC, “quoted”:http://martinfowler.com/eaaDev/uiArchs.html)
h3. How to break MVC?
If calling @#render_cell@ in the controller is “breaking MVC”, why is there a @#render@, or even a @#render_to_string@ method in the controller? That would mean Rails itself is doing something wrong, as it does rendering _in_ the controller.
It is absolutely ok _in_ the controller *to instruct a separate MVC-component to render* – as long as the controller doesn’t interfere in the rendering process or even shares knowledge about the cells internals.
h3. What is view code?
First, I’d like to emphasize I never said *views should be “_dumb, non-runtime-interpreted view code_”* – WTF? I use helpers, logic, everything in cell views.
Complex forms with dozens of fields, computations and conditions *are surely not “view code” only*, so in my opinion that _should_ be “abstracted out to a place where it simply doesn’t belong”: to a separate component.
However, there is *no need to put every little partial to a cell*. Don’t do that! It is a matter of feeling to perceive when things are getting too complex for a partial mess and should be refactored to a cell instead.
h3. Cells are more complex
This is absolutely true. Cells bring more classes and assets to your project. *It is a new paradigm that wants to be understood*. New programmers might be confused of cells suddenly popping up everywhere in your app.
Cells is a new concept in Rails – *of course it is more complex than odd partials* and helpers accessing global controller variables. It’s a bit like back in the times when OOP became popular and people asked “*Why should I use _objects_ when my simple procedures do all I need?*”. Cells are object-oriented components (with all the stuff we love about OOP, like inheritance) whereas partials are… whatever.
And, don’t forget Cells can be tested in a very simple and clean way, too. *This indirectly reduces complexity*.
h3. You are a nut!
I hope this writing clarifies several misapprehensions I created by posting a stupid simple example. Now, fire at will!
14 thoughts on “Rails Misapprehensions: Cells don’t break MVC”
Holy crap I planned to write this even before you thought of it I swear!
Good points. Especially on the lack of curiosity and will to understand new paradigms. Maybe there’s a lack of canonical examples, though.
this made my understanding of rails rendering and its mvc much clearer.
i will have a good look into cells.
thanks a lot!
How about posting a non-stupid more complex example? I am eager to see one..
I can’t agree.
I didn’t say that calling render_to_string doesn’t break the architecture, it does as well!
In your previous post you wrote:
“Partials can’t be rendered in the controller”
which isn’t true. Of course that’s evil but it’s possible.
Your approach is: render a cell in controller and then include every time you need a form.
What’s wrong with just calling instead? You do one thing instead of two. It’s more DRY isn’t it?
ehh sanitizer has eaten my examples 😉
Your approach is: render a cell in controller and then include @form_html every time you need a form.
What’s wrong with just calling render_cell(:beer, :complex_form) instead? You do one thing instead of two. It’s more DRY isn’t it?
I have not used cells. I truly want to see the beauty of using cells. Do you have a small sample app that I could look at? Right now cells just looks more complex to me. If I gave this to a junior developer I fear what the result would be. Please convince me. I’m open to change. I think I need more examples to change my opinion.
One example: Comments
Render cell inline on page request, render cell via ajax on added comment… excellent!
In my opinion the Cells project has big potential. Traditional Rails MVC: one controller -> one view -> many partials isn’t fully OOP.
The Google home page, where one can add many different gadgets, would be great example how Cells should be used.
I was always curious how Rails code should look like for a user configurable dashboard of some app. Additionally I want to have some of the widget available on other pages. View code can easily be divided into separate partials. But the question is how controller code should be divided.
@Bert and @Greg: If you want interactive cells with AJAX, be sure to try out Apotomo http://apotomo.de this is my widget framework based on Cells. I will release the 1.0.0 version in the next days!
@Michał: Sure dude, I abused your quote 😉 Nothing is wrong with calling render_cell in the view, I just wanted to show it might be called in the controller as well.
@Chris and @David: I started working on a blog application example which heavily uses Cells. I will put in on github soon, just follow me there 😉
Thanks for your comments, guys!
Although his example may have failed to make the point, I agree with Nicks intent.
“Cells bring more classes and assets to your project.”
Yes. And there is absolutely nothing wrong with that, rather the contrary is the case. If my two decades of experience in object-oriented programming have taught me only one thing, than this:
If there is a way to cope with the complexity of your domain (particulary to its changes over time), then this: to introduce as many classes and objects as you need to reproduce that domain with high fidelity.
If you find a discernible abstraction, you would be ill-advised to neglect the chance to model this abstraction. This is, what OO was all about in the first place.
And I guess, Adele Goldberg and the other veterans from the good old Smalltalk/MVC days would suppport this, either.
But actually the greatest contribution of cells are the workflow on some development teams thanks to cells. The technical part is another belief to subscribe on and not for everyone.
Most people don’t understand the original MVC applied to desktop apps is different than the MVC pattern applied to web apps. As an example, a view in traditional MVC updates itself when it receives a change event from the model. Web app views obviously don’t subscribe to events.
Rails does a lot of things in controllers it shouldn’t. I’m not a purist. I like simple. I like getting things done. Rails has the right balance of trade offs.
I never heard of cells but I’m interested.
@mark: You hit the nail. If you are interested in such an MVC pattern, check out Cells’ bro Apotomo (http://apotomo.de)