Sunday, May 12, 2013

Readable model name with translation support

Use following to have the translated attribute with fallback support,
This will look in to the translation in the following order,
First it will look for the "en.activerecord.models.person.first_name" and then for "en.attributes.first_name" and finally falls back to humanize.

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