UUIDs, state as records, database-backed everything
UUIDs, state as records, and database-backed everything.
All tables use UUIDs instead of auto-incrementing integers:
# In migration
create_table :cards, id: :uuid do |t|
t.references :board, type: :uuid, foreign_key: true
t.string :title
t.timestamps
end
Why UUIDs:
Fizzy uses time-sortable UUIDv7 (base36-encoded as 25-char strings):
# Fixtures generate deterministic UUIDs
# Runtime records are always "newer" than fixture data
# .first/.last work correctly in tests
Instead of boolean flags, create records to represent state:
# Bad - boolean flag
class Card < ApplicationRecord
# closed: boolean
def close
update!(closed: true)
end
end
# Good - state record with attribution
class Card < ApplicationRecord
has_one :closure, dependent: :destroy
def closed?
closure.present?
end
def close(by:)
create_closure!(creator: by)
end
def reopen
closure.destroy!
end
end
class Closure < ApplicationRecord
belongs_to :card
belongs_to :creator, class_name: "User"
# Timestamps tell you when it was closed
# creator tells you who closed it
end
Why records over booleans:
No Redis - everything uses the database:
# Gemfile
gem "solid_queue"
# config/database.yml