Wrote the first algorithm. Fond of analytical engines.
Roles — presence via add / remove
The same Address component declared twice, prefix: :shipping and prefix: :billing, and Phone as mobile and work — one row per slot in the shared tables, and none at all until a field is filled.
How this works
Make moderator is user.add(:moderator): one row in
markers under slot moderator. Remove moderator deletes it.
A marker has no columns of its own, because whether the row exists is the whole answer.
Save contact details writes only the slots that hold a value. Both addresses live in
the addresses table, which also holds the sellers' addresses and the orders' copies. The
slot is what tells them apart.
The declaration · app/entities/user.rb
component Name # user.name_given, user.name_family, user.name.initials
component Email # user.email_address, user.email_verified
component Image, prefix: :avatar # user.avatar_image.url
component Text, prefix: :bio # user.bio (the String), user.bio_text (the Text)
component Address, prefix: :shipping # user.shipping_address
component Address, prefix: :billing # user.billing_address
component Geolocation, prefix: :shipping # user.shipping_geolocation
component Geolocation, prefix: :billing # user.billing_geolocation
component Phone, prefix: :mobile # user.mobile_phone
component Phone, prefix: :work # user.work_phone
marker :moderator
marker :administrator
has_many :posts, via: :author # user.posts
has_many :comments, via: :author # user.comments
has_many :memberships, via: :user # user.memberships
has_many :employments, via: :user # user.employments — the seller side, same user
has_many :reviews, via: :author # user.reviews
has_one :basket, via: :customer # user.basket — the child's unique: true makes this a has_one
has_many :orders, via: :customer # user.orders
The rows behind it
| Where | Row |
|---|---|
entities |
|
names
default slot
|
|
emails
default slot
|
|
images
slot avatar
|
No row: avatar_image reads its column defaults
|
texts
slot bio
|
|
addresses
slot shipping
|
|
addresses
slot billing
|
|
geolocations
slot shipping
|
|
geolocations
slot billing
|
|
phones
slot mobile
|
|
phones
slot work
|
No row: work_phone reads its column defaults
|
markers
slot moderator
|
A row, with no other columns |
markers
slot administrator
|
A row, with no other columns |
Every slot row also has id, entity_id (this
entity's id) and timestamps. Ids are cut to their first block. The rows are the ones this page loaded,
so the panel adds no queries.