Wednesday, May 08, 2013

Online UML Creation with GenMyModel

As a software developer who collaborates often with other software developers, it sometimes gets tough to explain an idea well without resorting to some sort of visual aid. One such visual aid can be whiteboarding a UML diagram. This is often the Agile approach of drawing such diagrams, and it works quite well in person, but what do you do when you want to save a professional looking version of it in an online WIKI for later reference by other developers who join the team? Use a UML creation tool such as Visio or VisualParadigm. I've used the latter quite often to produce professional looking diagrams that I've used in software documentation, slide presentation, and blog diagrams. However, it comes with a heavy weight NetBeans based installation that takes a while to download and then later authorize with an account token. Enter GenMyModel, a new web application that is trying to change the game by providing an ultralight web interface for generating a UML diagram immediately on the fly, while providing image export, email sharing, and code generation features to boot.

Right now, GenMyModel.com supports UML Class Diagrams and UML Use Case Diagrams (partially). Here are examples of diagrams that I generated with it:

Order Class Diagram with State Design Pattern:

Event Management Use Case Diagram:

Soon, I expect them to support other diagrams, such as my favorites, UML Sequence Diagrams and UML Collaboration (Communication) Diagrams.

Check GenMyModel.com out in the mean time and give them your feedback on how to make their app better.

Until next time.   

Saturday, April 27, 2013

Managing Rails Routes When They Get Out Of Hand

Rails developers have gotten really good over the years in breaking down logic in beefy controllers to business domain logic that lives in Models and some reusable control logic that lives in Controller Modules. Not only does this address cohesion concerns, but also the lines per file recommended limit of no more than say 200 in Ruby or 400 max.

However, what I have not seen done often enough in most of the projects I've worked on is handling of these concerns in the Rails Routes file "routes.rb". I've often seen gigantic routes files that not only take a long time to detangle and understand, but also aren't organized in any fashion as to the grouping of routes per business domain area (e.g. Feature A routes, Feature B routes, etc...), which brings us to the topic of this blog post. :)

If you simply follow the software engineering recommendation to break files into smaller ones once they've surpassed a limit of say 400 lines, then a route file (typically 500+ on bigger Rails projects and sometimes 1000+ or even 2000+) is naturally to be broken into multiple route files.

There are several techniques for doing it, but here is one easy technique that I've used on the last couple of Rails projects I was on:

1. Break routes.rb along these lines: Static Routes, Admin Routes, Account Routes (e.g. authentication with devise), and Per Feature Routes (e.g. Company Management Routes, User Personalized Info Routes, etc...)

2. Create directory "config/routes" to store smaller route files

3. Create a route file under "config/routes" for each one of the functional areas mentioned in Step 1, named "XYZRoutes" and holding a Ruby module like the following example:

module Routes
  module AccountRoutes
    def self.draw(context)
      context.instance_eval do
        devise_for :users, :controllers => { :registrations => "registrations", :sessions => 'sessions' }
        devise_scope :user do
          get "/login" => "sessions#new"
          delete '/logout' => 'sessions#destroy'
          get '/logout' => 'sessions#destroy'
          get '/register' => 'registrations#new'
        end
      end
    end
  end
end


4. Update routes.rb to look like this:


Dir.glob("#{Rails.root.to_s}/config/routes/**/*.rb").each {|route_file| load(route_file)}

SomeApp::Application.routes.draw do
  Routes::StaticRoutes.draw(self)
  Routes::AdminRoutes.draw(self)
  Routes::CompanyRoutes.draw(self)
  Routes::AccountRoutes.draw(self)
  Routes::UserRoutes.draw(self)

  mount JasmineRails::Engine => "/specs" if defined?(JasmineRails)

  root :to => "home#index"
end

This should provide you with a good blueprint for how to better organize routes files in Rails.

To summarize, break down routes.rb in Rails when it gets over 400 lines of code for the following benefits:

  • Higher cohesion per route file, improving general understanding of that area's focus as well as ease of maintainability by allowing you to find URLs for a particular domain area faster.
  • Better management of route content by not having to scroll through 100s of lines of code (sometimes 1000s) to find the URL that you want to change

I've worked in an environment once where the development team wrote an internal library to streamline modularization of routes.rb. If you know of a public open source one, please mention in comments.

Wednesday, December 12, 2012

Rails 3.1 Asset Syncing to S3 on Heroku

Rails 3.1's Asset Pipeline is a wonder in management of static assets in modern web development. It streamlines the process of gzipping, minifying, and fingerprinting asset files as well as setting HTTP cache headers and integrating into a reverse-proxy cache server such as Rack-Cache (comes with Rails) or Varnish.

On Heroku's new Cedar stack however, one cannot use a high-performance static asset server like Nginx or even a high-performance reverse-proxy server like Varnish. So, the next high-performance option, which is arguably higher-performance is remote asset hosting on Amazon S3 or a CDN (Content Distribution Network) like Amazon Cloudfront.

Fortunately, one gem - asset_sync - comes to the rescue. It automates syncing of static assets from your app to S3 or a CDN upon asset compilation.

I used it to serve static content from S3 for a website I am architecting, so I would like to share these tips with anyone who has attempted to follow Heroku's asset syncing guide:
https://devcenter.heroku.com/articles/cdn-asset-host-rails31

If you try to have it sync automatically on deploy to Heroku, it fails miserably due to Heroku not loading its ENV variables in production mode. We missed that when we deployed to staging because asset syncing was working there during the Heroku asset compilation step.

To avoid falling for that trap, you need to compile assets locally, commit, and push. Unfortunately, this can get painful with setting all the ENV vars for asset_sync or passing it options that are supposed to be secure passwords you do not want to put in the git repo.

I wrote a rake task (inspired by a colleague's rake file) to automate the process of grabbing the ENV vars from Heroku instead, compiling, committing, pushing, and then deploying to heroku all in one command.

Code:
https://gist.github.com/4273735

Usage:
rake deploy app=heroku_app_name branch=branch_to_deploy

Alternate syntax:
rake deploy[heroku_app_name,branch_to_deploy]

Default branch as master:
rake deploy[heroku_app_name]

Saturday, November 24, 2012

Heroku DB Migration from PostgreSQL to ClearDB

I have been recently working as the software architect of a Ruby on Rails application running on Heroku, and as part of the work, we decided to migrate off of Heroku's default PostgreSQL database into the MySQL based ClearDB.

To do so, I tried relying on Heroku's taps gem, but it produced mediocre results with some MySQL database columns not matching the same null or default value constraints in the source PostgreSQL database.

I ended up coming up with my own approach to perform a successful perfect database migration, and I would like to list the steps over here for anybody else who might undertake the same endeavor since the Heroku and ClearDB guides do not include any migration instructions as of today from the Heroku PostgreSQL database.

Prerequisites

  • Setup PostgreSQL database ("brew install postgresql" then follow post-installation instructions. version 9 would do)
  • Setup ClearDB on your Heroku app and add SSL keys to your application as per their instructions
  • Obtain pg2mysql_cli.php tool from over here: http://www.lightbox.ca/pg2mysql.php and extract it to a local directory, under which you will run the commands mentioned under the instructions section.
  • Obtain the URLs for the PostgreSQL and ClearDB databases from Heroku by running the command "heroku config -a appname"
  • Extract the username, password, host, and database name from the database URLs as mentioned in the Heroku PostgreSQL guide and ClearDB guide
    • For example: 'mysql2://someuser:somepassword@us-cdbr-east-02.cleardb.com/somedatabase?reconnect=true' should yield: username "someuser" password "somepassword" host "us-cdbr-east-02.cleardb.com" and database "somedatabase"

Migration Instructions

Turn on Heroku's maintenance page to stop write traffic into the database

heroku maintenance:on -a appname

Backup the Heroku PostgreSQL database

heroku pgbackups:capture -a appname

Download the Heroku PostgreSQL backup

curl -o b001.dump 'heroku pgbackups:url -a appname'

Restore PostgreSQL backup locally in order to convert to uncompressed format

pg_restore --verbose --clean --no-acl --no-owner -h localhost -U local_postgres_db_user -d postgresdbname b001.dump

Generate new uncompressed data-only backup (format most appropriate for ClearDB)

pg_dump -U local_postgres_db_user --data-only --column-inserts --format p -f b001-data.sql postgresdbname

Run pg2mysql_cli.php command from the pg2mysql tool directory to convert PostgreSQL backup to MySQL backup

php pg2mysql_cli.php b001-data.sql b001-data-mysql.sql

Clear ClearDB MySQL DB completely

MYSQL="mysql -h us-cdbr-east-02.cleardb.com -u someuser -psomepassword -D somedatabase"
 $MYSQL -BNe "show tables" | awk '{print "set foreign_key_checks=0; drop table `" $1 "`;"}' | $MYSQL
 unset MYSQL

Set ClearDB as the main DB for the Heroku app (assuming you are relying on SSL for security and followed the ClearDB instructions for settings it up)

heroku config:add DATABASE_URL='mysql2://someuser:somepassword@us-cdbr-east-02.cleardb.com/somedatabase?sslca=cleardb-ca.pem&sslcert=someuser-cert.pem&sslkey=someuser-key.pem&reconnect=true' -a appname

Initialize ClearDB schema from schema.rb in the Rails app

heroku run 'rake db:schema:load' -a appname

Clear any database tables that got populated in the schema initialization process

MYSQL="mysql -h us-cdbr-east-02.cleardb.com -u someuser -psomepassword -D somedatabase"
 $MYSQL -BNe "show tables" | awk '{print "set foreign_key_checks=0; delete from `" $1 "`;"}' | $MYSQL
 unset MYSQL

Load ClearDB with MySQL backup data obtained from the Heroku PostgreSQL DB

mysql -u someuser -psomepassword -h us-cdbr-east-02.cleardb.com -D somedatabase < b001-data-mysql.sql

Migrate

heroku run 'rake db:migrate' -a appname

Seed

heroku run 'rake db:seed' -a appname

Turn off Heroku's maintenance page

heroku maintenance:off -a appname

That's all folks! Questions and comments are welcome.

Thursday, July 12, 2012

Software Craftsmanship vs Software Engineering

Here are the slides of the long edition of my recent talk "Software Craftsmanship vs Software Engineering", which was given at McHenry Software Crafstmanship, Chicago Software Craftsmanship, and South Bend Software Craftsmanship:

Wednesday, April 25, 2012

RailsConf 2012 - My Talk Slides

Here are the slides to my talks at RailsConf 2012.

It was nice meeting all of you at the conference. For those looking for a software development opportunity with self-growth potential, hit me up by email (last slide). Cheers!


Tuesday, April 03, 2012

Software Craftsmanship vs Software Engineering at The South Bend Software Craftsmanship (Apr 2012)

I am presenting on Software Craftsmanship vs Software Engineering at The South Bend Software Craftsmanship on April 17, 2012:
http://www.meetup.com/sobesc/events/59019232/?a=ea1_grp&rv=ea1

Abstract:

The recent emergence of the Software Craftsmanship movement in the last decade has been accompanied with quite a bit of confusion on what the movement is exactly about and whether it adds any value beyond previous software development movements, such as Agile and Software Engineering.

In this talk, Andy Maleh will define Software Craftsmanship, compare and contrast to Software Engineering, and provide actual examples on how both disciplines are playing out at the Groupon software development environment. At the end of the talk, attendees will be given a chance to ask questions and share their own insights on the topic.

Bio: Andy Maleh is a Software Engineer at Groupon who specializes in user needs analysis and building transformative software that meets ongoing demands. He leads by embracing agile practices and software craftsmanship in the process of perfecting Groupon's deal experience. He joined Groupon via Obtiva, where he served as a Senior Consultant for more than five years. Andy is also the Founder and Lead Developer of the Glimmer open source project for Desktop Development with Ruby. Andy holds an M.S. in Software Engineering from DePaul University in Chicago and a B.S. in Computer Science from McGill University (Montreal). Outside of Groupon walls, Andy plays the drums in indie rock venues and travels via Longboard when the Chicago weather permits.

The event is hosted at the Greenhouse at Innovation Park (Notre Dame). 1400 E. Angela Blvd., South Bend, IN, USA.