Sunday, May 5, 2013

Encapsulate views in rails

We always hear that we have to keep our code clean and DRY. But I feel that poor view files are always left out from this concern. We do not write html to support the change of DOM. Yes, true for rails we have layouts and partials. But these features some times is not enough for encapsulating views.
Let's say we are using jQuery UI in our application and we want to switch to twitter bootstrap :-S. Now that will be a pain, right? Because you have all sorts of views and DOM structures designed for jQuery UI. So for projects that we plan to maintain for a long time, we should consider to encapsulate almost every thing. Such as we can use unobtrusive Javascript to have the flexibility to switch between JS libraries. But in this post I plan to discuss the view layer and a particular mehod to encapsulate DOM and view logic.
People are already doing it. Rails form builders, simple form, active admin DSL can be some of the examples. Obviously we can use partials to reduce the duplication but here I am talking about dom structure.
So here is the pattern that is used by simple form or form builders, you might call it the builder pattern. Here is a simple example which will clear the cloud I think.

I would prefer to encapsulate the view with a DSL as following,
Here is the helper code to support the DSL.
And the target resulting dom is as follows.

The DSL is fairly simple actually. The two things you need to know before hand is how capture method works for rails template and that you have to pass the self as template so that later you can call the capture method using the template object. Any method that you can run from the view, you can run on template object.
As you can see for widget we I have used an object to as we need related sub blocks(title, content). You can also use the simpler version which is shown in header block. Usually form builders need the object reference as they have states. But for us widgets donot have states. Still it is a good way to go, because later you might have different type of widget and then, you might pass that as argument. In that case your widget will have state and the w object will help you to maintain that state. I hope that helps :)

References

3 comments:

Anonymous said...

I like your idea, encapsulating view concern.

Usually we tend to do lotta stuffs on view, moreover these days views are not solid html alone. we are using JS frameworks and other view end grooming tools.

So i think views are getting shipped with different scopes these days. for an example, we have handlebar template for gendering partials over JS.

I think this encapsulation is not bound in ruby based DSL anymore rather in different platform. (JS framework)


Thanks for sharing :)

Unknown said...

Good one. Also, Rails partials can be used as a template or layout out of the box.

http://railscasts.com/episodes/99-complex-partials

Jitu said...

Thanks Hasan vai and Sohan vai for your valuable comments. This approach is more like a presenter which is described here. This kind of object based DSL is important where the method may behave differently depending on the widget object, giving you more control on how each widget will be rendered. And surely it can be used in other technologies as well, as already told be Hasan vai.