elt547

elt547

So I’ve opted for the “easy method” of polymorphic associations, where you have a column for each possible polymorphic type. That’s the database implementation, but now I’m wondering what to do on the schema implementation.

The table looks something like this:

Table inbox_items {
  id int [pk]
  profile_id int [ref: <> profiles.id]
  
  post_id int [ref: < posts.id]
  poll_id int [ref: < posts.id]
  comment_id int [ref: < comments.id]
}

Is there a way for me to add a virtual field to the schema so that I can cast to and from the correct column? That way I could just create it like %InboxItem{association: %Post{}} and it would know to save the id to the post_id column. Similarly can I make it able to respond to something like Repo.preload(inbox_item, :association) so I can fill the virtual field when loading?

Showing Posts 1 to 9

cmo

cmo

Are you sure about that?

You can create a custom ecto type but I would reconsider if this is the path you want to go down. You’ve read the ecto guides on the subject?

elt547

elt547 OP

Yeah, it’s the first method shown in the guide. It’s really just one workaround or another, because the polymorphic association is what I need more or less. Do you have any alternative suggestions? I tried the many-to-many method and it was a nightmare, and the guides are remarkably incomplete on the subject.

I read a few blog posts but they all recommended against the more complex approaches. I had implemented the many-to-many and it was awful, and I considered table inheritance in postgres but was advised against it.

Actually almost my entire domain has these kinds of relationships. I really shouldn’t be using a relational db but I really wanted to use elixir, and I have limited graph db experience so I don’t want to deal with more learning since I’m on a time crunch to get my mvp shipped.

Matsa59

Matsa59

Hello maybe I don’t get what you want but I think polymorphic_embed | Hex could helps you

elt547

elt547 OP

Thanks, took a look at that. It’s not quite what I need but nice to know it exists.

I’m basically just trying to do a different version of:

Table inbox_items {
  recipient_id int [ref: > profiles.id, not null]
  
  inboxable_type varchar [not nul]
  inboxable_id int [not null]
}

I’m trying to do it in a way that preserves referential integrity. Thing is, a lot of the other methods have flaws that are imo worse than being without an FK constraint.

MRdotB

MRdotB

https://mrdotb.com/posts/ecto-exclusive-belongs-to-aka-arc/

What about exclusive belongs to. You make your inbox_items hold fk for all your other models

elt547

elt547 OP

That’s what I’m using in the database side of things. What I’m trying to avoid having to do blow apart the schema with several different possible associations on every load from the db and save.

Thought the link you sent was one I’d seen before. See now that it’s not, checking it out.

elt547

elt547 OP

That worked for assigning it to the correct column. For some reason I didn’t think of using pattern matching to assign the association. I supposed I could do the same thing if I used a virtual attribute. Do you have any idea how I could maybe load the correct struct into the virtual field with queries? Otherwise I’ve got to check :post_id, :poll_id, :comment_id etc manually. Is there a way I can make preload work to load the association?

MRdotB

MRdotB

# you want to left_join and preload the fields
query =
  from(
    item in InboxItem,
    left_join: post in assoc(item, :post),
    left_join: poll in assoc(item, :poll),
    left_join: comment in assoc(item, :comment),
    preload: [
      post: post,
      poll: poll,
      comment:comment 
    ]
  )

items = Repo.all(query, opts)

# I don't think it will be possible to set the virtual_field in the ecto query
# You can do something like below to set it but I think this part should be done
# in the view
Enum.map(items, fn item ->
  model =
    cond do
      is_binary(item.post_id) ->
        item.post

      is_binary(item.poll_id) ->
        item.comment

      is_binary(item.comment_id) ->
        item.comment
    end
   # add the model to the virtual field manually
  %{item | virtual_field: model}
end)
Kurisu

Kurisu

Hypothetically speaking, if we can write a query that preload the good association by finding the one that is not nil, could we use something like :

select_merge: %{virtual_field: preload_querry()}

I have no idea of how to write that hypotheticall preload_querry though…

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
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
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
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
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

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
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
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
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

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews