elt547

elt547

Can I fake a polymorphic association with a virtual schema field?

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?

Most Liked

elt547

elt547

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.

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

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)

Last Post!

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…

Where Next?

Popular in Questions Top

vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
Lily
In templates/appointment/index.html.eex: &lt;%= for appointment &lt;- @appointments do %&gt; &lt;tr&gt; &lt;td&gt;&lt;%= appoi...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New

Other popular topics Top

baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 49084 226
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 42533 114
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement