“The Great Punjab” seemed to be the ideal place our next round of Josh Nights – the spicy Punjabi food adding more zeal to the discussions.
Sandip started off proceedings with talking on what is Active Record Inheritance, when and how it should be used, the benefits and pit-falls. His presentation is available here. For the record (no pun intended), Active Record is of 2-types: Single Table Inheritance and Multiple Table Inheritance.
Sandip has planned out an excellent example using products. A gist of this would be:
- Use STI if your models have share common properties (or data) and you want to avoid duplication or redundancy.
- Use polymorphic relations when your models having different data want to exhibit common behaviour.
Nothing is really worth it without examples —
Sandip explained how a 2 Products -a shirt and a pen should use STI to ensure that everyone gets a common SKU and other properties. Its easy to look at the products via the Product model and also seamlessly access the shirts from Shirt and the pens from Pen model. However, when it comes to purchasing the products, (like order processing, shopping card etc.), the Purchase model should be polymorphic in nature to cater to purchase of different products!
For those well versed with Databases:
- In STI, the fields of the parent table are duplicated in the children.
- In polymorphic relations, there is a composite keys with suffix _type and _id which determine the relation.
Though all of us use Models everyday, this insight into Active Record Inheritance was good learning ! While everyone was digesting this stuff along with their drinks, Kiran started his talk on Acts As State Machine AASM. His presentation is here.
A succinct presentation which was to the point. Why do we need AASM and the perils of overuse!
Converting a state diagram into states and events makes development easy and accurate. guards protect the state transition. He explained how recently we had to insert a new state in a life-cycle for a model and it turned out to be ridiculously easy.
We have a model called Contest, which had states :incoming, :opened and :closed. Different actions occur when each event is triggered. Now, we had to insert a new state called :moderation between :opened and closed.
Earlier code was:
aasm_event :open do transitions :to => :opened, :from => :incoming, :guard => Proc.new { |contest| contest.start_date <= Time.now && contest.end_date >= Time.now } end aasm_event :close do transitions :to => :closed, :from => :opened, end
This code change was trivial:
aasm_event :open do transitions :to => :opened, :from => :incoming, :guard => Proc.new { |contest| contest.start_date <= Time.now && contest.end_date >= Time.now } end aasm_event :close do transitions :to => :closed, :from => [ :opened, :moderation ] end aasm_event :moderate do transitions :to => :moderation, :from => :opened, end
Had this been a if/else or switch statement, there would have been a lot of code change! Now all we added was an element in an array and we were on our way. Another interesting fact about AASM which gets missed out was that each state and event automatically adds a named scope or a method for use! So, once the states are introduced, we automatically have access to some model methods:
contest.opened? contest.open!
Kiran also introduced the next-gen AASM using StonePath Its an interesting read too! Well that wraps up what happened at the latest Josh Nights!