Sign up Sign in Samples Blog contact support
track name and type changes




  • lots of information lost
  • can't fully revert to previous states



this is going to involve a substantial overhaul of revisions system.  Here are the proposed changes:


    add "db_content" field
    stop using current_revision_id field 
   # note: updated_at and updater_id should be updated when (and only when) there is a new transaction involving either the card or one of its "field descendants", meaning that if someone updates A+B, that is registered as an update to A but not to B.  So if only fields other than name, type_id, db_content, or trash are updated (eg codename), this change should not alter these fields.
card_revisions table:
    gone, replaced by card_transactions, card_actions, and card_changes
card_id             # all acts are associated with one root card
actor_id            # card id of user)
acted_at           # datetime)
action_type      # create, update, and delete  (could do mapped numbers)
field                      # name, type_id, db_content..trash?  something for files?  (could do mapped numbers here,too)
Why add content to cards table?
  • consistency: this makes it so that all the main fields are stored the cards table, which becomes a complete representation of the current state of the deck.  You can reproduce the entire deck (without any history) with this table alone.
  • performance: WQL no longer needs to do a join (which would now be a much more complicated join) to get this info
  • code simplicity: there is currently a bunch of special handling for content because of its special status.  with this representation we'll be able to get rid of all the attribute tracking code.
Why call it "db_content"?
  • Following rails convention (and using rails code!), each database field is associated with card methods, like @card.db_content.  To avoid errors, it is best if database content is distinguished from other content values, which may be overridden by *structure rules for example.  In general, the db_content should not be manipulated directly by the API as frequently as the post-structural processing content, so we want to make it less tempting to make this mistake.

What's the difference between card_act and card_actions?

  • Every card_act will involve one or more card_actions.  When someone creates a Claim, for example, this will involve creating several other cards (like the +source card).  There is just one act, but each subcard has a separate action.  
Is the card_actions table really necessary?
  • Not strictly.  You could stick the card_id in card_changes, treat "trash" as another field, and then either infer the action (eg, if trash is set to true, it's a deletion) or add an action field there.  It's worth discussing the merits of the two approaches in greater depth, but this seems very precise, clean, and robust.
migrating old data from card_revisions
id ->
created_at -> card_acts.acted_at
creator_id -> card_acts.actor_id
card_id -> card_actions.card_id
content -> card_changes.value
# migration notes:
  • card_changes.field will always be content for the stuff coming from card_revisions, but we may also add name/type changes with create actions for all cards (?).
  • if the card isn't in the trash, the card_actions.action_type will always be create or update (easy to infer - first one is create)
  • if the card is in the trash, there should also be a delete action
  • the hard part will be grouping card_actions into card_acts.  We can probably infer this too based on timestamps




an obvious comment: we definitely need good indexing here.


we'll need to think a bit about the handling of current_revision_id, especially in the context of files/images. Each of those urls has a revision_id in it; we will need to make sure we keep that same id (could be in card_actions or card_changes). But we don't really want to have to do db lookups for those every time someone requests an image. We could keep the revision_id in the table, but I was looking forward to getting rid of that... perhaps an instance variable?

--Ethan McCutchen.....2014-08-18 19:56:14 +0000


+Relevant user stories