Burn Installer Officially Launched!

Woohoo, after like 2 months of hard work, the WiX Burn installer (which I talked about in the previous post) is finally launched on our website at www.inflowinventory.com/Download, as well as www.download.com!

Check out the installer to get a taste of what WiX Burn can do! I think most can agree that the our new installer has a much better user experience 🙂

Woohoo, after like 2 months of hard work, the WiX Burn installer (which I talked about in the previous post) is finally launched on our website at www.inflowinventory.com/Download, as well as www.download.com! Check out the installer to get a taste… Continue reading ‘Burn Installer Officially Launched!’

Leave a comment

Rails single table inheritance with polymorphic association

Lets say, you wanted to store contact information such as emails, phone numbers, and websites. These contact information can be associated with an employee of a business or the business itself. A business can have multiple emails and multiple phone numbers. Similarly, an employee can have multiple emails and multiple phone numbers. In Rails, we can store all these contact information in a single table using both the polymorphic association and single-table inheritance. First, lets see how we can use polymorphic association to deal with the contact information.

We have the following active record models for a “Business” and an “Employee”:

class Business < ActiveRecord::Base; end
class Employee < ActiveRecord::Base; end

For the contact information, we have the following active record models:

 

class Email < ActiveRecord::Base; end
class PhoneNumber < ActiveRecord::Base; end
class Website < ActiveRecord::Base; end

Now, for the associations, Business and Employee models can have many emails, phone numbers and websites. And conversely, Email/Phone Number/Website can belong to either a Business model or an Employee model. How do we make up the association?

Rails ActiveRecord provides an association called “Polymorphic” association. Using polymorphic association, a model can belong to more than one other model, on a single association. Here is how this can be implemented:

class Business < ActiveRecord::Base
has_many :emails, :as => :emailable
has_many :phone_numbers, :as => phonable
has_many :websites, :as => webable
end

class Employee < ActiveRecord::Base
has_many :emails, :as => :emailable
has_many :phone_numbers, :as => phonable
has_many :websites, :as => webable
end

class Email < ActiveRecord::Base
belongs_to :emailable, :polymorphic => true
end
class PhoneNumber < ActiveRecord::Base
belongs_to :phonable, :polymorphic => true
end
class Website < ActiveRecord::Base
belongs_to :webable, :polymorphic => true
end

Having the above setup, you can get a collection of emails for a business instance via the call “@business.emails”. Similarly, you can get a collection of emails for an employee instance via “@employee.emails”.

Now, if you really think about what a contact information is? It basically contains a label and an information. I.e. Personal Email: test@gmail.com, Business Phone Number: 1-800-999-9999, Business Website: www.google.com, etc.

So, we can say that an email, a phone number, or a website is an instance of a contact information class with two attributes: a label and an information. Thus, we can store any type of contact information in a single table.

In rails, if you name a column “type”, by default ActiveRecord allows inheritance by storing the name of the class in the column type. You can overwrite the Base.inheritance_column to change the name of the column where the class name is stored. Now, changing our polymorphic associations as “contactable”, we can have the following setup:

class Business < ActiveRecord::Base
has_many :emails, :as => :contactable, :class_name => "Email"
has_many :phone_numbers, :as => :contactable, :class_name => "PhoneNumber"
has_many :websites, :as => :contactable, :class_name => "Website"
end
class Employee < ActiveRecord::Base
has_many :emails, :as => :contactable, :class_name => "Email"
has_many :phone_numbers, :as => :contactable, :class_name => "PhoneNumber"
has_many :websites, :as => :contactable, :class_name => "Website"
end

class ContactInformation < ActiveRecord::Base
belongs_to :contactable, :polymorphic => true
end
class Email < ContactInformation
# any validation for email can go here
end
class PhoneNumber < ContactInformation
# any validation for phone numbers can go here
end
class Website < ContactInformation
# any validation for website urls can go here
end

All the emails, phone numbers and websites will now be stored in the table associated with the model “ContactInformation” and will have the following setup:

create_table :contact_informations, :force => true do |t|
t.string "contactable_type"
t.integer "contactable_id"
t.string "type"
t.string "label"
t.string "info"
t.timestamps
end

Now, when you create a business email:

@email = @business.build.emails(:label => "Personal", :info => "test@gmail.com");
@email.save!

the record will be saved in the table “contact_informations” with the values “Business” for the “contactable_type”, @business.id for the “contactable_id”, and “Email” for the column “type”.

Similarly, for employee phone number:

@phone = @employee.build.phone_numbers(:label => "Work", :info => "1-800-123-4567");
@phone.save!

the record will be saved in the table “contact_informations” with the values “Employee” for the “contactable_type”, @employee.id for the “contactable_id”, and “PhoneNumber” for the column “type”.

Rails makes it really easy to do a single table inheritance with polymorphic association.

Lets say, you wanted to store contact information such as emails, phone numbers, and websites. These contact information can be associated with an employee of a business or the business itself. A business can have multiple emails and multiple phone… Continue reading ‘Rails single table inheritance with polymorphic association’

13 Comments

A better installer

So about a month and a half ago, I was driving home from work one day after working on some NSIS installer code (which in my humble opinion is very ugly and hard to work with), when I had the thought “How come no one uses managed code to write installers?”. Managed code is so much cleaner to read, and the .NET framework is so powerful. Most of the time we’re just copying files, writing registries, and running some msiexec anyways right? nothing managed code can’t handle.

So I did a little bit of googling and then found this amazing new beta release of WiX 3.6. In the beta release there is a new bootstrapper/downloader module named Burn which allows you to chain multiple MSIs together (something WiX was lacking for a very long time), download packages online, and use managed code to create the bootstrapper interface. After reading about the features here and trying out the Visual Studios 11 Preview installer, I was pretty convinced to give it a shot.

After using Burn for a while, I can say that there are some clear advantages with using managed code to write a bootstrapper. The first advantage is that it allows you to streamline your interface in so many different ways… for example, you don’t have to create a page where you “accept the license agreements” anymore, since most people don’t read that anyways. It also lets you create an experience where the novice users can simply click an install button, without having to select all the customization options.

Another advantage is that you can use all the features of Windows Forms and WPF to create your interface. So this allows you to use all types of different controls and animations to create a much better looking user interface.

There are disadvantages of using a managed bootstrapper though, because it requires that the user has the .NET framework installed on their computer. Thankfully, Burn also handles that for you. When Burn fails to run the managed bootstrapper, it will run a separate bootstrapper to install the .NET framework first. Following that, it will run your own installer.

Some more disadvantages of using Burn right now, is that there is almost no documentation, and that there are still some bugs in the framework. In terms of the documentation, you really have to be prepared to do a lot of googling to find the answers that you’re looking for. Sometimes, I had to dig through the open source C++ code to get a better understanding of how the Burn engine works.

For those that want to give the toolset a try, here are some tips that I think will be helpful:
1) Read http://blogs.msdn.com/b/heaths/archive/2011/10/28/introducing-managed-bootstrapper-applications.aspx
2) Download the WiX source and take a look at the project stored in “wix36-sources\src\Setup\UX”. It contains the managed code that was used to create the WiX installer
3) Dig through http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/ when you need to find answers

So about a month and a half ago, I was driving home from work one day after working on some NSIS installer code (which in my humble opinion is very ugly and hard to work with), when I had the… Continue reading ‘A better installer’

Leave a comment

TextMate 2 Tips

tl:dr:To celebrate the long-awaited releaset of TextMate 2 this week, my friend Kevin and I have started a new tumblelog called Text Mate 2 Tips to offer simple visual tips on how to use the new features of our favourite text editor.

Way back in 2005, watching screencasts of Rails developers working in TextMate and the almost telekinetic way they could manipulate code with it was a big reason I finally switched to a mac.

As time wore on, and the release of TextMate 2 slipped further and further, the update became a canonical example of vapourware, right along side Duke Nukem. People started abandoning TextMate looking for something new that could replace it. And, though I dallied with several of these contenders, none of them fit as transparently with the way I work and think in code.

So, I was excited earlier this week to learn that an alpha version of TextMate 2 has finally been released to the public, and it’s nowhere near as horrible as Duke Nukem Forever.

There was one problem; though there were many new features in the long-awaited release, documentation was scant. It was a challenge to hunt for bits of intel through trial and error and Github commits. So I decided to start a tumblelog to capture the tips and tricks I discovered and to solicit tips to share from others. The TextMate 2 Tips blog was born. The response has been overwhelming with core TextMate developers contributing tips. And I am honoured that we even got a nice link from the Macromates blog!

If you are a TextMate user and want to take advantage of all the features of the new release, then check out the blog or follow tm2tips on twitter, and if you’ve got a tip submit it and we’ll share it on the blog.

tl:dr:To celebrate the long-awaited releaset of TextMate 2 this week, my friend Kevin and I have started a new tumblelog called Text Mate 2 Tips to offer simple visual tips on how to use the new features of our favourite… Continue reading ‘TextMate 2 Tips’

3 Comments

Building tomorrow

Conventional wisdom says you should listen to your customers. Most people will agree to that without questions.

The idea of listening to the people you serve – be they customers, users, etc, becomes so prevalent that the discipline of gathering feedback and reacting to them have been codified into repeatable models. In marketing, you have survey, focus group, etc. In project management, you do requirements gathering, prototypes, inviting client feedback, etc. And now recently, even in building a company, you have the lean startup model.

The good thing about this is that it reduces risks. After all, if your target group gives you the stamp of approval, it’s hard to imagine things will go wrong later.

This is all good if we want incremental improvements on well-defined problems – logically sensible and emotionally comforting next steps.

But what about radically new ideas?

Ideas that require huge amount of effort to build. Ideas that will take time for people to understand and adopt. Ideas that ultimately change how we live and work.

If we go back in time, how do you think a focus group of random strangers will react to Twitter, before Twitter becomes so popular? How about to the internet, before internet’s time? How about a computer, before Microsoft?

As a company, not only should we listen to our customers, but we should go one step further: imagine and deliver something that makes radical improvements, and, through that, build a better tomorrow for everyone – even if everyone might not fully understand it today.

“If I had asked people what they wanted, they would have said faster horses.”
Henry Ford, founder of Ford Motor Company

Conventional wisdom says you should listen to your customers. Most people will agree to that without questions. The idea of listening to the people you serve – be they customers, users, etc, becomes so prevalent that the discipline of gathering… Continue reading ‘Building tomorrow’

Leave a comment