jdumont

jdumont

I’m back with another SQL / database structure question. I feel it’s related to polymorphism, STi and all those concepts, but seems inverted in my case (one parent type, many children; rather than many parent types to one child).

A simplified example — not the one I’m actually working with — would be the concept of a Document entity owning multiple different content types. Let’s say, Video, Image, Markdown, etc where each has a different structure and fields, but share an index field, so that all of the different content types for a given Document can be loaded and then displayed in order. Is this polymorphism?

Would something like an intermediate entity (Content for arguments sake) with an exclusive arc for the different content types and foreign key for the document be a suitable solution?

Given I’m using PostgreSQL and it has better support for querying embedded fields, would I be better off just dumping a JSON array into a field on the Document?

EDITED TO ADD: Just thinking through the problem a little more, simply embedding an array of maps/JSON won’t work, as within those maps I’ll want to reference records in another table.

Showing Posts 1 to 10

jdumont

jdumont OP

I deleted this topic after deciding that my answers were already scattered around the forum in the various polymorphism and inheritance topics. Here I am a week later, still failing to find what I feel is an adequate solution to a relatively simple problem.

In a relational database (or any other table based one for that matter) how would you model the above — where a document/page/record/whatever is composed of many different types of content?

For example, the record that I’d want to pull from the DB would look something like this after whatever joins, etc were done:

%Document{
  name: "Example",
  id: 1,
  content: [
    %Video{
      index: 0,
      url: "something.com/ajsha",
      description: "all about the video",
      author_id: 3,  (%User{})
    },
   %Title{
     index: 1,
     text: "My title"
   },
   %Image{
     index: 2,
     url: "something.com/akshgdakj.jpg",
     caption: "Blah blah",
     uploader_id: 5, (%User{})
     photographer_id: 28, (%User{})
    },
    [...]
  ]
}

Thinking about it, this would have been equally relevant when I was putting together the schema for my CrossFit app recently. A solution to this could help there to.

Others have referred to this problem as a polymorphic has_many as opposed to the polymorphic belongs_to that is often talked about (and has solutions in the Ecto docs). That topic has been my main point of reference, although I’m not wedded to the idea of an Animal => Cat/Dog/Whatever relation as the original poster.

I’ve scratched my head, got my Google-fu on, read some books and even explored other means of storing the data and still can’t really work it out.

Help me! :sweat_smile:

dimitarvp

dimitarvp

Naively asking before thinking about it deeper – have you considered trying PostgreSQL’s table inheritance?

jdumont

jdumont OP

Truthfully I think I checked out Postgres’ table inheritance at some point but skipped over it after finding a reason it wouldn’t work/be ideal. I think it was something to do with Ecto not supporting it, but I’ve got no aversions to escaping into SQL if needs be.

I’ll take a proper look at it again and see whether it fits the bill or not.

A lot of the recent talk around here abut DB-less applications or making the DB an implementation detail has piqued my curiosity though. I’ve realised that when modelled without Ecto - just using Elixir structs - the problem is simpler and a lot of the code I’ve written thats only there to try and contort my data into tables just falls away.

I’m either still not “thinking in tables” or I genuinely have a use case where a different storage solution would be better (same goes for that CrossFit app). It’s kind of hard to know without more experience.

OvermindDL1

OvermindDL1

Yeah this seems like a classic use for postgresql inheritence. You can use foreign table links too. And yeah, Ecto could use some help in supporting it but it still ‘mostly’ works. ^.^;

The structs in structs method you mention would be like traditional foreign linked tables though, which is perfectly fine.

jdumont

jdumont OP

Of the two (inheritance and foreign table links) which would you opt for, and are there any “gotchas” that I should keep an eye out for?

(Trying to make up for my lack of experience here)

OvermindDL1

OvermindDL1

Honestly I’d just use foreign linked tables, easy to expand, easy to conditionally join (left_join’s), etc…

jdumont

jdumont OP

So you’d have a intermediate table that would hold the document_id, index and then a column for each content type (video_id, image_id, title_id, markdown_id`, etc) where only one can be set at a time - a.k.a. an exclusive arc?

Would having an additional type column on this intermediate help with joining on the correct column, or would there be some SQL’y way to join on the non-null column that I don’t know about?

Sorry for all the questions. I just want to properly understand what I’m doing and why, so that I can apply it to other scenarios.

OvermindDL1

OvermindDL1

Well I’d do it the other way, I’d have a document_or_whatever table with rows that have columns that everything shares, then other tables like video, image, etc… of who’s primary keys is not an auto-incrementing integer but is rather a foreign table link back to the document_or_whatever. This will be highly efficient and infinitely expandable. :slight_smile:

You can actually create a constraint that enforces that when one is created then no others exist, this constraint can be shared by them all so only one can exist at a time easily as well.

jdumont

jdumont OP

So the two rows across the two tables that make up a complete record in effect have the same primary key? In the main document_or_whatever table (probably go with content) I have a column called id that matches up to a column an id column (the primary) in the video, image, etc tables?

So when querying the data, I’d find the right row(s) in the `contents table and then left join on all the possible other tables where the primary keys match?

I think I understand…

OvermindDL1

OvermindDL1

Yep yep, the main table defines the ID to use and everything else’s ‘primary key’ just matches it with an enforced foreign link. :slight_smile:

Yep yep! You can even extend such joins dynamically if your system becomes pluggable later or so too. :slight_smile:

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
apz
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews