The mysteries of size, length and count

ActiveRecord Association and ActiveRecord NamedScope have subtle differences in the way they respond to size, length and count (based on whether records are eager loaded or not) that sometimes leads to some weird results and one can easily land up spending some time debugging these issues.

For more details on this behaviour see 

http://www.wuputah.com/2010/05/24/count-size-and-length-associations-vs-named-scopes/

http://blog.hasmanythrough.com/2008/2/27/count-length-size

So when you want the actual count always call the .all method or do an explicit reload and then call any of the three methods. It helps rely on Array or the collection of reloaded results to give the right result rather than interfering with eager loading, unsaved records and other such stuff. 

 

My experiences with page caching

Lately I have been working on a legacy rails project which had page caching in place. Here are a few points I think are takeaways for me from my experience with it:

1) Page caching is useful on pages which have more or less content related to same resource. If you have multiple kind of unrelated content loading on the page which expire at different times, then the page cache may not be of much use. And you may be clearing out the entire cache for that page unnecessarily when one piece gets updated thus affecting your performance.

2) When page caching comes into picture you can’t have user specific code in the server side code for those pages. Particularly, beware of putting in cookie checking code on the server side. It should probably not be there anyways, but yeah if you have it for some reason, do not forget that you are using page caching. One may argue that why would one use page caching for user specific content anyways, but on pages where extremely minimal stuff is user specific, it is very easy to forget that there is page caching in place. And then you will land up having pages cached in a state based on the first viewer of that url and all other users would see that view. 😦 

Ofcourse you can have javascript to handle your dynamic content.

3)  Do not depend only on ui interfaces to clean up your page cache. Admins who don’t understand it completely will keep clearing your cache every now and then and your pages would perform poorly. Have sweepers for observing content and deleting the corresponding cached pages automatically (which is the natural way for page caching invalidation 🙂 ) rather than admins taking a guess that this particular page cache needs to be cleared when I update this content.

Page caching can lead to a lot of performance boost if the above points are kept in mind since then the time required for the request to process would be just the time required to send back the html. And extremely expensive requests would start serving almost in the same time as normal requests.  

For more details on page caching and dynamic content on cached pages see 

http://railscasts.com/episodes/89-page-caching

http://railscasts.com/episodes/169-dynamic-page-caching

http://railscasts.com/episodes/89-page-caching-revised

http://railscasts.com/episodes/169-dynamic-page-caching-revised

observe_field in rails

There used to be this method observe_field in rails upto v2.3.8 under ActionView::Helpers::PrototypeHelper. To give more details – here is the snipper from apidock

observe_field(field_id, options = {}) public

Observes the field with the DOM ID specified by field_id and calls a callback when its contents have changed. The default callback is an Ajax call. By default the value of the observed field is sent as a parameter with the Ajax call.

You need to specify url for the ajax call / a javascript function that you want to execute on the change of the field. Additional options give you flexibility to specify how frequently the action is supposed to take place, options to specify more parameters to the ajax call. 
The use case for this is something like selecting from a dropdown, and updating some content on the page based on the selection. 

However the caveat here is, you cannot do something like the jQuery live functionality. If you have more select boxes coming up later after the page has already loaded, your ajax calls won’t happen on selecting something from the new dropdown. 

Secondly this seems to work only for the change event on fields although on dom elements I would like to have reused the same method for multiple other events like ‘click’, ‘mouseover’, and so many more.

In addition, there is an observe_form method that can help out a bit with the 1st problem by observing all fields within the form for changes, however with dynamic elements (not in the original source of the form) coming up it again fails. (Jquery has made life so much easier and natural rather than trying out weird solutions to do stuff like this.)

So whats up with this method now?

This method has been deprecated. In fact the PrototypeHelper has seen a lot of change. Legacy prototype helpers are available as a plugin now. https://github.com/rails/prototype_legacy_helper in favour of making Rails 3 agnostic of javascript frameworks.

Ofcourse, jQuery can handle the above scenarios with much more flexibility and cleaner code. 

So if you are upgrading a legacy project which has usages of observe_field, it would be advisable to go for jQuery and keep it clean, simple and working 🙂

Rails: Multiple validations on single condition

Came across this scenario, where we needed multiple validations to kick in on the same logical condition. It landed in repeating the condition for all the validation statements. But stumbled upon this option.

with_options :if => :email_notification_required? do |condition|

    condition.validates_presence of   :email_recipient_name

    condition.validates_length_of   :email_recipient_name, :maximum => 255, :allow_blank => true

    condition.validates_presence of   :email_address

    condition.validates_length of   :email_address, :maximum => 255

end

(The italicized fields are specific to the example. )

So all the validations in the block kick in only if the boolean method email_notification_required returns a true.

This may not always be the way to go, there may be indications that probably this is not the right place for all those validations, perhaps they can be moved out, but nonetheless, its an option you may need sometime.