Sunday, September 25, 2011

Rails is not MVC

There is a terminology problem in the Rails community.

Everyone promotes Rails as a MVC framework. I did that as well. However, the truth is that Rails represents the Model2 architecture. It's not MVC. 

I know it's just a definition issue. Maybe we shouldn't care. It wasn't really a problem until recently. We see the rise of the JavaScript MVC topic, which is an awesome thing. The browser clients with its JS engines can have a real MVC, as opposed to Model2.

OK, so what's the difference?

In short, we're talking about MVC when a model can notify (through the Observer pattern) the views about the changes. It's not possible in a classical Rails app (it's possible when you use WebSockets, Pusher or a similar technology, but it's not so popular yet.). MVC was popular in desktop apps.

On the other hand, Model2 is exactly what we do with Rails. We don't notify the views from the model, the controller simply passes the model data to the views and handles the html generation which is then sent to the browser.

There's an interesting pattern evolving recently that a Rails app simply serves as a backend for a mobile app and all it does is exposing a JSON/REST API. It's similar to Model2, but instead of generating HTML it generates JSON. Still, it's not MVC.

You can read more about UI architectures in this article by Martin Fowler

Why is it important?

It's becoming an issue now, because we start talking more about the JavaScript MVC. The JavaScript MVC is a real MVC. The models can easily notify the views. Often, when you talk to people being introduced to the JS MVC they seem to be confused and try to implement the Model2 pattern on the client side, which in my opinion is ridiculous.

What shall we do about the Model2 and MVC confusion?

I see three choices.

The first one is to say that MVC changed its original meaning and Model2 can also be called MVC. In that case we can start using terms like "classic MVC" or "real MVC" for the old MVC. This is what is happening now, but I don't think that changing definitions is a good idea. It brings even more confusion.

The second way is to promote the fact that Rails represents a Model2 architecture and MVC is reserved to, well, MVC. It's going to be hard, but we will keep the definitions stable.

The third way is to just ignore the confusion. Who cares?

I decided to go with the second option. What's the best way in your opinion?

 If you read this far you should Follow andrzejkrzywda on Twitter and subscribe to my RSS.

27 comments:

Thorsten Müller said...

Hi Andrzej,

nice article, interesting links. I didn't make up my mind what to do about it yet. I think we could call it a Model2-MVC to clarify things without confusing newcomers too much. There is so much documentation out there that talks about MVC.

On the other side I agree, that new technologies in the mobile sector will change the game and we will have to be careful about the correct terminology when talking about the patterns of interaction between frontend and backend. Same goes for browsers, where websites get more and more interactive and demand a faster information flow, http being stateless notmaking this task easy to begin with.

Anonymous said...

This is a bit silly. Most definitions of MVC I've read don't actually specify much 'behavior'. MVC is about separation of concerns - keeping model related stuff distinct, independently testable, etc, from the views that are their UI, with controllers functioning as the bridge.

Seems to me the fact that Rails doesn't act like some strict old definition of MVC you found is that the web just doesn't really work like that, as you point out re: websockets. Rails is adhering plenty close to the definition.

In short, I choose option 3 because following the spirit of the law is far more important than following the letter. It's MVC because that's how it's conceptually organized, and it's how we think about organizing code written with it.

Andrzej Krzywda said...

Thorsten: Thanks

I like the Model2-MVC idea. You're right that there is so much documentation about Rails being MVC that we need to be careful about changing it.

My prediction is that in the future Rails apps will become data serving backends. All the UI will move to the clients, be it JS+Html or iPhone.

In fact, we have more and more projects where our apps are just backends to mobile clients. Interesting things are happening.

Anonymous said...

Actually, 'C' in "MVC" corresponds to Controller...

Andrzej Krzywda said...

"old definition of MVC you found"

That's exactly the point. I'm just not sure that if a definition is old then we should abandon it.

The MVC was firstly used in 1979. It's 32 years now. Model2 is known since 1999.

"spirit of the law is far more important than following the letter"

Yeah, I see your point. I also got used to calling Rails MVC. What would you suggest to call the MVC where models can notify views?

Anonymous said...

But the Ruby way is to ignore confusion.

Jan Dudulski said...

Don't say "Rails" here - problem is more general. It's about whole webframeworks family.

Andrzej Krzywda said...

Jan:

True. Many other similar frameworks claim to be MVC. Django was honest from the beginning - they used the MTV term.

Hosh said...

I don't think this matters.

Server-generated HTML DOM is obsolete. It won't go away completely, but computing have moved on to beyond the desktop.

The question is, does making a distinction between MVC and Model2 give you an advantage in making choices? Does it help you think better when you program and make better technical decisions? Does it give you an insight that gives you an edge, an advantage?

The answer is 'no' in all cases. Therefore, MVC vs. Model2 in Rails is not very useful.

Andrzej Krzywda said...

Hos:

"Server-generated HTML DOM is obsolete. It won't go away completely, but computing have moved on to beyond the desktop."

I agree.

"The question is, does making a distinction between MVC and Model2 give you an advantage in making choices?"

Yes, it makes the communication easier.

I'm teaching Rails at University and it doesn't help me when I have to say "Rails is MVC, but it's not really MVC, it's Model2". I could ignore that, but I don't want to teach things that are not really true.

Kevin Rutherford said...

Heh, you beat me to the punch. I was just about to blog the same thing! Good post.

Anonymous said...

Rails is organized like an MVC. That's what matters most to me. WebObjects is similarly organized and it's described as an MVC framework.

ambert said...

Spot on post! Awesome.

I had always been scratching my head on this ever since I started doing iOS and JS dev.

Then I read this http://amix.dk/blog/post/19615 and it started to make sense

chrome___ said...

Hey,

thanks for the good post. Unfortunately, "MVC" has become a bit of a marketing term, to the point where it's viewed to be kind of a blemish not to be "MVC" when in fact it may make perfect sense to use another pattern in a web context; eg. Model-View-Presenter or variants as described by Martin Fowler.

Orion Edwards said...

So rails can't be called MVC because it doesn't notify the views of changes? By that logic neither is ASP.NET MVC, Django, or any other of the millions of web MVC frameworks...

It'd be easy for rails to send notification events from the model, but it'd also be pointless as the view only lives as long as the HTTP request.

Trying to say that you can't call rails MVC on the back of a minor and optional feature seems like you're just trying to stir the pot. Boo.

Anonymous said...

The HTTP protocol imposes a Model 2-like relationship between client and server. But the model exists in Rails, if even by proxy.

Saying Rails is Model 2 is an oversimplification. And saying Rails misrepresents itself as an MVC framework shows an ignorance of web framework history.

The MVC idea in web frameworks comes from WebObjects, the standard set in the 1990s for all web frameworks to be measured by. It's proven to be a useful organizational framework.

Purists may not like it, but it's immensely helpful in communication among team members.

Anonymous said...

Add AJAX and presto! Rails is MVC.

W said...

"The question is, does making a distinction between MVC and Model2 give you an advantage in making choices? "

To me it's obvious the answer is yes.

A big chunk of the problem that Andrzej has happened onto here is that people aren't using MVC to describe any particular pattern anymore. It's started to have a general use meaning (as others have pointed out) "separation of concerns".

Picture a more extreme version of this, something like "well, yeah, I just used 'design patterns' in my code." Which ones? Yeah, a lot of the hype about design patterns is pretty overwrought, and some named patterns are more useful to know than others, but the fact is, it remains quite useful to be able to communicate some things about the organization of interlocking pieces of code with some short compact phrases.

Having a distinction between Model2 and "MVC" means I can know something specific -- not just generally philosophical -- about an app using it before I even start using it. That's half the advantage of any framework in the first place, and it's nothing to sneeze at.

"Server-generated HTML DOM is obsolete."

I sentence you to 2 years without a desktop computer, iPhone, or Android device. Time off for good behavior will be determined by whether or not you seem to demonstrate an appreciation for HTML's overwhelming success as a client presentation layer and the limitations of devices you apparently don't spend much time with.

orthorim said...

I've been doing or trying to do MVC in Java for over 10 years. It was always a goal but not always easy or intuitive.

Then along came iOS and iOS is truly, by convention, full on MVC. It makes for great code, and helps to mask many of the issues that come from using an ancient programming language like Objective-C. Only now do I fully understand MVC.

Rails is most definitely not MVC - in part because it's a web framework and there just isn't the same level of interactivity. I didn't know there is a name for what it's doing so Model 2 seems to me a very good idea.

Richard said...

I was going to say it sounds very academical and noticed you are teaching Rails in university. :)

As a programmer, I would say Rails is MVC, if anything then let's call it re-defined MVC.

The fact is, MVC is so hot now a days just because Rails claims it is MVC. If Rail call itself Model2 then the hotest thing now would be Model2. And those new "real MVC" frameworks would call themselves Model2 as well. And somebody may find Rails is not Model2.

I think it is very simple. The terms are theories. The focus of real implementation are what work best. If it fits theory 100% then it is not real.

Justin Forder said...

The original MVC (as originally implemented in Smalltalk) is not distributed - all the parts are in the same memory image. Model 2 is an interpretation of MVC which accepts the constraints of the Web (pre-Ajax) - placing the view and the capture of user events in the browser, and the the model and controller (interpretation of user events) in the server. People have always (well, since 1999) used the term "Model 2 MVC" when they wanted to be precise, but in the context of web applications it has become common to refer just to "MVC". I don't think you would be able to persuade the Spring MVC and ASP .NET MVC projects to change their names - but they are Model 2 MVC frameworks, too.

Tartley said...

Hey. With respect, I don't agree with people saying "it doesn't matter" or "that old defn of MVC is obsolete".

That may be true if all you ever write is code that uses web frameworks. But there is a much larger body of work out there (i.e. all the other software in the world) for which the 'classic' definition of MVC is still very active, current, and in daily use.

I therefore feel that it's overall easier and less confusing for the web frameworks communities, now that the distinction is becoming apparent, to correct their historical accidental misuse of the term.

This is especially important when teaching students, since they will be encountering many different types of systems, not just web frameworks.

Best regards.

Sheldon Hearn said...

Y'all enjoying flailing away at Andrzej's straw man?

See the History of Model 2 at http://en.wikipedia.org/wiki/Model_2:

"The second milestone was the claim that Model 2 provided an MVC architecture for web-based software."

Model 2 is a context-specific refinement of MVC.

Except for Justin, you're all arguing about whether we should call an elephant a mammal or a pachyderm. Yo, all pachyderms are mammals, check it.

TomaszZielinski said...

It's a purely academic discussion.

Speaking of Django, one can see Controller as a mix of Django-provided machinery and user-written Django views. In such setup MVC Views are just templates.

Or one can also see both Controllers and Views as "entities" that consists of server (Django) and client (user agent) parts.

Within Views defined in such way, one can employ MVC or MVVM (sub-) patterns. Etc, etc..

Really, there's nothing productive in such discussions, they only have a potential for flame war ;)

Andrzej Krzywda said...

@Tomasz

I didn't expect that this post will trigger such controversy :)

All I wanted was to point out that there is a terminology problem.

Yes, it is a bit academical and it's not the end of the world if we keep saying that Rails is MVC :)

I like some of the suggestions that we can call it Model2-MVC, as opposed to real MVC.

I stay with my opinion that Model2-MVC is quite a bit different from MVC. They are different architectures under the hood. What they have in common is some kind of separation between Model, View and Controller. The communication is much different, though.

apohllo said...

As it was pointed out, the Model2 was not introduced as an opponent of MVC, but as opponent of Model1. Both of them were defined in the context of Java Web Applications not applications in general. So naming Rails design Model2 seems very odd to me.

Still I do agree that such distinctions should not be ignored. But they are good, if they convey meaning to the language users. MVC does what it should, since it is many people know that it is Model-View-Controller. Model2 is name which is understandable mostly for the Java people. I guess MVC works in opposition not to Model2, but rather to spaghetti code, since it introduces the strict separation of layers (Model1 seems to be a good description of "spaghetti code").

Even though MVC is described as defining the Model-View observer interaction, which is not available in WEB applications, this is not the primary feature of the pattern. So if you really want to make a distinction based on it, I would suggest that "Web MVC" is much better and more meaningful than Model2.

Anonymous said...

Yes, please make the distinction.

When I was first learning Rails (around 2006/2007-ish I think), I was confused at the MVC terminology.

I kept trying to figure out if the Model was able to update the view dynamically.

Even in those days the distinction wasn't academic for someone familiar with the MVC or observer patterns. Now the distinction becomes even more important, with developers doing more and more client-side.

So I'm all for it.

As an aside, it would be nice if there was a JS framework that would create a real JS MVC model, based on a Rails model. Is there such a beast? A Rails-Sproutcore bridge or some such?