Model, View….. Coffee!
MVCoffee is a suite of software tools written in CoffeeScript and Ruby that provides a client-side Model View Controller (MVC) framework and cache. It’s designed from the ground up to work closely with (and take advantage of the coolest features of) Ruby on Rails.
Version 1.1.0 is now released!
Source on github:
To get a feel for how MVCoffee does some of the things it does, check out these demos:
The Philosophy and Benefits
Yes, there are a lot of other client-side MVC frameworks out there. Most of them are somewhat one-size-fits-all, in that they don’t have an opinion about the server-side technology used. MVCoffee could potentially be used with any server-side solution, but it is specifically designed to work closely with Ruby on Rails. Its approach is inspired by the Rails way of doing things, and it takes advantage of and enhances many of Rails’ features, like routes, model associations and validations, metaprogramming techniques and Turbolinks.
The guiding philosophy is this. Caching has both benefits and pitfalls. Rails can make server-side caching easier, but ultimately it’s optional. If you can get by without the benefits, you don’t have to worry about it.
The same is not true on the client.
If you think about it, a web page is a cache. It’s a snapshot of some of your data, frozen in time and held onto indefinitely. Unless the user navigates to another page, or unless you do something explicitly to refresh the data should it become stale, you may be displaying out-of-date data to the user. Or worse, you could be allowing the user to interact with out-of-date data!
Like it or not, you face the pitfalls of cached data on the web, so you might as well enjoy the benefits. If you’re dealing with invalidating stale data (and it behooves you to!), you might as well not be reloading data that isn’t stale. Know whether it’s stale or not, and do the right thing accordingly.
Here are some of the things MVCoffee does to help you keep the data on the client fresh while gaining improved performance:
ejs) templates that look almost identical to the familiar Rails embedded Ruby (
<route>_pathfunctions for generating URL’s within the app. This client side rendering can be completely agnostic as to the source of the data, whether it’s from a first time page load over
html, a refresh via Ajax
json, or an inexpensive rerender of cached data already on the client.
- Automates refreshing potentially stale data. Users frequently will be visiting your
app in multiple tabs, browsers or even devices at the same time. MVCoffee detects
when a page could be potentially out of date and fires the
refreshmethod on all running controllers. All you have to do is specify what should be refetched and recached on a refresh.
- Fills in some holes in Turbolinks with a process called “clientizing”. Turbolinks unobtrusively follows GET anchor
It does NOT, however, provide this same convenience for any kind of
formon the page out of the box. This means normally
Provides Rails-style validations and associations on client-side models, with a familiar Class Macro-like syntax for defining model attributes. Although you have to Repeat Yourself to define the client models, this pain is eased by the similar syntax, and could conceivably be automated in the future.
it = class MyNamespace.User extends MVCoffee.Model it.has_many 'item' it.validates 'name' test: 'presence' it = class MyNamespace.Item extends MVCoffee.Model it.belongs_to 'user' it.validates 'sku' test: 'numericality' only_integer: true
Requires only a few lines of client code to make an input form automatically validate against the associated model and submit to the server over Ajax only if valid. This saves you having to repeatedly make the same jQuery
.submitintercepts and Ajax calls.
@item = new MyNamespace.Item @addClientizeCustomization selector: "#item_form" model: @item
- Provides familiar Rails server-side functionality on the client, such as the flash, session and errors array.
remain live (preserving the cache), and even allows redirecting after a
jsonrequest over Ajax.
- Normalizes browser behavior concerning pausing and resuming your application.
Desktop browsers fire
onfocusfor the window and do not stop timers when your window receives an
onblur. Safari on iOS, on the other hand, does stop timers but does not fire
onfocus. MVCoffee normalizes this and provides a
resumelife cycle for client-side controllers. (Note: Android and Windows browers have not been tested at this time!)
- Saves you typing with the usual “convention over configuration” way, alleviating the need for the whole
respond_to do |format|business by normalizing
To learn more, check out the guides:
Next: Cache Demo