Active Record Inheritance, AASM and more

“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!

Posted in Uncategorized | Tagged , , , | Leave a comment

Custom Capistrano recipes, VIM shortcuts and more!

Diversity is the life of a party – and a Josh Night warrants this.

We had reserved a remote table for 12 at Green Park — a nice garden restaurant which gives us enough scope for animated behaviour!

Capistrano Custom Recipes

Ninad started the proceeding after the customary rounds of beer, whiskey were ordered. He spoke on customizing Capistrano tasks for a clustered setup. He explained that though there are standard cap commands to combat a cluster deployment, there are few tasks which help you to maintain these clusters.

For example, if you need to analyze logs from a cluster of 3 slices, a cap shell command is required to be invoked to get the logs from all 3. A custom Capistrano recipe command however can be easily used to get the log file (from a particular date, or number of lines etc.) and output parsed for processing.


# Below namespace/task is used to view logs files from
# all the servers in the single console

namespace :logs do
  desc "tail production log files"
   task :tail, :roles => :app do
     run "tail -#{ENV['nol']} #{shared_path}/log/production.log" do |channel, stream, data|
       puts  # for an extra line break before the host name
       puts "#{channel[:host]}: #{data}"
       break if stream == :err
     end
   end
end

# Usage
cap logs:tail nol=100  # tail -100
cap logs:tail nol=f    # tail -f

The discussion forked out into some basics of Capistrano too (which was some good learning for new members):

  • cap deploy:rollback and its benefits.
  • The different Capistrano roles: webserver ,db and application
  • Using the Capfile for a custom deploy.rb script – you can specify which deploy script to load for capistrano instead of the standard config/deploy.rb

This also forked new conversations regarding load-balancing, using nginx as a web-proxy and various other nginx directive and even into cloud deployments on Engine Yard.

Load-balancing is of 2 types: a hardware load-balancer or a software load-balancer. A hard-ware load balancer is configured with a Virtual IP (which is the externally set as the ‘A’ record for a domain) and every request is then internally routed to different slices depending on the load. A software load-balancer like Nginx distributes the requests it receives between different nginx workers. So a combination of a hard-ware load balancer and nginx — gives tremendous concurrency and scalability.

Among the various nginx directives is the less frequently used for allow / deny IP address. Gautam explained how one of our clients requested us to configure nginx to deny access to all users from Romania! Using http://www.countryipblocks.net/ for Romania, we added a denyip.conf file and included it in the nginx.conf

VIM shortcuts

Gautam then spoke on productivity and how to use VIM key-board shortcuts effectively. The presentation was given in a vim file itself. Couple of screens here:

For a detailed presentation have a look at this gist. When you are on a remote terminal (especially if you are logged into a production / staging server), you have no option other than vim. At this point, simple things matter :

  • faster navigation control
  • copy / pasting code (copy from Clipboard via mouse select and terminal paste can cause numerous problems, starting from alignment issues to special characters getting added.)
  • Multiple file and buffer control
  • No mouse!

The tips would help improve not just support productivity but also keep a clean coding and development practice.  Using .vimrc and macros efficiently, syntax highlighting and tab settings improve productivity. “Vim for the modern Rubyist” is an excellent resource of how to integrate git and rails commands into your vim console!

At the end of these two sessions and a number of rounds of drinks and food, we had an open hour for random questions and answers:

  • Engine Yard instances, environments and their new CLI deploy. Using the new CLI deploy resolves the headache of installing chef recipes via S3 bundles. Its also easier to use.
  • What is Database sharding? How its done and various ways to do it.
  • RAID and its uses in web-deployment.

We ended the session with deciding when the next party will be and who will speak.

Of course, we also paid the bill :)

Posted in Uncategorized | Tagged , , , | 2 Comments