LostKobrakai

LostKobrakai

I do a lot of php development in a cms/cmf called processwire for a living, while curiously looking into elixir/phoenix. ProcessWire’s entity modeling is based on a modeling strategy, which I found to be more flexible, than only the plain has_one/has_many/… relationships most frameworks seem to use/suggest.

Before explaining it in more details: My question is, if such a structure would be possible to use with ecto/phoenix and what you think might be the downsides/dealbreakers for it.

So modeling in processwire is not based on a single table per model, but models are rather a core set of infos about the model entity (id, name, template, created, modified) and a set of custom fields associated to the model (template). Each of the custom fields does have it’s own table, which in simple cases consists only of entity_id and data columns, but it certainly can hold more columns if needed by the type of field like sort for multi-value fields.

So a template for a blogpost, which does hold the custom fields of “title”, “tags” and “body”, would result in the following tables:

templates (has the info about which fields the blog post is associated with)
entities (base info like above)
field_title (one-to-one mapping of title to post)
field_tags (one-to-many mapping of tags to post)
field_body (one-to-one mapping of body to post)

Via the template information on each entity the data of the custom fields can be joined into the base information or being lazy loaded after the retrieval of just the core information about the entity.

The advantages of such a mapping to me are the following:

  • All entities ids are stored in a single table, which makes linking of entities of any kind super simple.
  • All entities can have has_one or has_many relationships to their fields, so multi-value fields are simple to do as well

Both together allow for structures, where an entity can link to a sorted list of differently typed entities without additional pivot tables or such things. For example in a portfolio website a project entity’s field aside_info could return a list like this [%Image{}, %VimeoEmbed{}, %Image{}, %Image{}].

A second feature of this modeling strategy is that data can easily be stored in a tree structure. By adding a parent_id column to the entities table everything can live in a global tree of all the entities in the system.

With every model entity being of the same base, one also does rather care about how to store data relevant to a specific type of field instead of creating a title (varchar(255)) on each model again. One does rather compose exisiting fields with fields unique to a specific model.

This might not be a perfect layout of what happing in processwire, but I tried to keep the explanation reasonably short. I curious to hear your thoughs about it.

Showing Posts 1 to 6

sztosz

sztosz

Doesn’t it make inefficient?

Can you show example database schema (dump) and models?

yurko

yurko

I think its doable as a generator, similar to phoenix.gen.model https://hexdocs.pm/phoenix/Mix.Tasks.Phoenix.Gen.Model.html

you could “steal” its logic and extend it to represent this structure

LostKobrakai

LostKobrakai OP

@sztosz
It surely is less efficient, but that’s the price for every abstraction one does use. On the other hand it’s a super flexible way of modeling data. But really in my line of work (low to medium traffic websites) the query speed was never an issue. On the other hand developer speed/efficiency is. I especially found, that being able to link any arbitrary data in a system without much fuss is super useful.

For a raw sql dump you can take a look at this one: https://raw.githubusercontent.com/ryancramerdesign/SkyscrapersProfile/master/site/install/install.sql
It’s a subset of the information available here (take a look in the backend, too): http://demo.processwire.com/

sztosz

sztosz

I don’t like it. There’s too much generalization for me. But I don’t like software that let you build tailored to your needs solution by clicking things in “wizards”/“creators”, sooner or later you hit the wall and have to write custom code anyway.

But I also think it’s dooable.

Downsides? Too much abstraction and generalization. Complicated queries across many tables. Complicated mapping of business models to database entities. .

LostKobrakai

LostKobrakai OP

Not sure where you see “much generalization” in this approach, when you can still have exactly the fields you need on a model. If you really have some special kind of data you cannot store in an existing type of those fields you can always add a custom one. For me it’s also less about the “clicking things in wizards” but rather a case of not having to do the hard stuff for the 95% that don’t need special attention, as long as I can still implement custom solutions for the 5% which really are custom.

Your point of the mapping of business model to database model on the other hand is totally valid. It does certainly require an abstraction over ecto/sql to query this kind of data structure to be useful.

sztosz

sztosz

I think I misunderstood whole concept at first. But now I don’t really see advantage of another abstraction layer with this

over just having simple relationships like this:
Project has_one aside_info (a foreign key in DB)
aside_info has_one or has_many as a foreign key to each of the tables images, vimeo_embeds.

And calling Project.aside_info_by_project_id(project_id) could simply return same list [%Image{}, %VimeoEmbed{}, %Image{}, %Image{}] where aside_info_by_project_id is really a SQL Query with simple joins and mapping to proper structs.

Anyway I really don’t understand why keep all entities basic info in entity table (and custom fields each in other table).

I don’t understand why would you wan’t to link random entities of totally not related types. Or I simply don’t understand whole sentence :joy:

In traditional 3NF having multi-value fields is super easy too. But we don’t have to sacrifice efficiency for single-value fields.

All in all I either still don’t understand the advantages of that alternative way or simply gives a layer on abstraction that obscures things instead of simplifying it. And I’m not shy to admit that i fear it’s the first one, lack of understanding :blush:

— All posts loaded —

Where Next? Top

Trending in Discussions Top

AstonJ
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
2977 94592 917
New
cblavier
Hey there, It’s been more than a year since we started using LiveView as our main UI library and building a whole library of UI componen...
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
heathen
Quite interesting article Google brought me. Didn’t find any mentions about it here. What do you think in general? Would you use togethe...
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
AstonJ
Since we have deprecated our Erlang sections (as we have dedicated Erlang Forums now) let’s add this thread for those who’d like to post ...
New
Null-logic-0
What IDE or editor are you using for Elixir development? Personally, I use Zed, and I really like it, but sometimes I wish there were a ...
New

Other Trending Topics Top

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
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews