During last week’s SUSE HackWeek, I worked on solving two problems we recently had in the Ruby on Rails part of SUSE Studio. The first is to easily define unique identifiers, and the second makes it simple to add new configuration to a database.
Assigning UUIDs to your models
Some time ago I was asked if we could add UUIDs (Universally Unique Identifier) to one or two (or three...?) of our models. I first looked at the available gems and plugins for doing that, but they all relied on the fact that the according model has a dedicated column for the UUID.
I was too lazy to write migrations for each of the models of course, so i decided to write a gem which makes it super-simple to add UUIDs to models: The result is UuidIt.
Once the gem is installed all you have to do in order to assign UUIDs to a model is adding one line of code:
class Car < ActiveRecord::Base uuid_it # <-- that’s all. amazing, no? :) end
1 down, 1 to go :)
Conveniently adding and managing seed data
In SUSE Studio, new features are often added with special configuration toggles so new features can exist in our codebase in a dormant state. This technique allows us to test new code on our development and staging clusters but not have it show up on susestudio.com until it’s ready.
Until recently, these switches resided in YAML files, and this mostly met our needs. Lately, we have had rapid development of amazing new features and needed more flexibility. Our needs for feature switching grew from toggling a feature on or off to being able to support more advanced configuration, such as enable features for certain groups of users or appliances only. We also wanted to be able to change those settings on-the-fly without reloading the webserver to pick up the changed YAML files.
We thought, “Ok, let's just keep those settings in the database and add a few more columns for additional attributes! This should be easy, right?” It turns out to be not as easy as it seems — at least to get it right. We ran into questions like, “Where would you keep the seed data and when would you load it?”
There are many approaches how to load and manage seed data (YAML files, migrations (this is bad, please do not do this), Rails’ db/seed.rb, seed_fu, etc.)... but none of these solutions really worked for us. We needed:
- automatic loading of new objects
- automatic updates for already existing seed objects
- possibility to override seed data and not get the changes reverted
- possibility to define associations where you do not necessarily know the primary key
To solve these issues (and a few more), I came up with has_alter_ego. It’s simple to use, too: Simply add a call to
has_alter_ego to your model
class Car < ActiveRecord::Base has_alter_ego end
...and you automagically have the objects which you define in the according YAML file available in your database. Currently, it gets the job done well. I also have a few features which I plan to implement in the near future, too.