-
Notifications
You must be signed in to change notification settings - Fork 4
Migrations
Migrating tables under low_card_tables
works almost identically to without low_card_tables
. (Obviously, the table structure is different, but migrations themselves change almost not at all.)
Key Hint: Keep any VARCHAR
fields (or other such fields) in your low-card table limited to relatively short lengths — e.g., :limit => 20
or whatever. Many databases impose a restriction on the maximum width of an index key (in MySQL InnoDB, it's 767 bytes); if you simply say t.string :foo
in your migrations, this creates a VARCHAR(255)
, and it only takes three of these to exceed that limit. Generally speaking, this isn't much of an issue, since you're storing only strings with programmatic meaning in a low-card table, anyway.
There are a couple of key exceptions:
- Low-card tables require a unique index across all attribute columns (and in fact the
low_card_tables
gem tests for this index, and will blow up and refuse to run if it's not present), and so there's support for automatically creating and maintaining this index. - Removing columns from a low-card table is slightly more complex, exactly because of the requirement that there always be a unique index and thus exactly one row in the low-card table for each unique combination of attribute values. There's automatic support for this, too.
As mentioned previously, there must always be a unique index on all columns in a low-card table. Fortunately, low_card_tables
will create and maintain this index for you automatically — all it has to do is know that a table is a low-card table. It can do this in one of two ways:
-
Explicitly: if you add
:low_card => true
to the optionsHash
of migration statements likecreate_table
,add_column
,remove_column
, orchange_table
, it will know it's a low-card table. -
Implicitly: if there is a model defined for a given table, and it declares
is_low_card_table
, thenlow_card_tables
knows that it's a low-card table.
(Hint: it never hurts to be too explicit. ;)
Either way, when columns are changed on the table in question, low_card_tables
will first drop the unique index, then run the migration code, then recreate the unique index automatically. low_card_tables
always names the index something like index_user_statuses_lc_on_all
; it will truncate the embedded table name as necessary to maintain an index name that's not too long for your database system. However, the index can be called anything at all — the code simply verifies that there is a unique index over all columns in the low-card table, not that it is named anything in particular.
(See also Options — the unique index will not cover, and is not required to cover, columns like created_at
or updated_at
that are not conceptually attributes on the low-card table.)
If you need to perform several migration operations at once, or run any code at all, and want the unique index dropped and created only once, simply do the following in a migration:
change_low_card_table(:user_statuses) do
...any code at all...
end
The index will be dropped before executing the block and added after it, and automatic dropping/adding of the index disabled for the duration of the block.