chrisdel101

chrisdel101

Ecto many-to-many problem caused by embedded schema

I’ve spent several days trying to make my this work, connecting my tables using Ecto Association Guide – Ecto v2.2.11

I think Many-to-many associations in phoenix and ecto - #5 by marick might work.

But now my embedded schema is screwing things up. It is not part of the DB, and it only used for the UI, but I think I still need it.

I thought embedded schemas were not supposed to effect the DB? Is there an way around this?


# this works
org = %{name: "Toys R Us", slug: "toys-r-us"}
org_c = Organization.changeset(%Organization{},  org)
org_insert =  Repo.insert!(org_c) |> Repo.preload(:employees)  

# this does not - error is due to the .preload(:organizations)
emp = %{last_name: "schmo", first_name: "joe", role: "owner", email: "joe@schmo.com", password: "password"}
emp_c = Employee.registration_changeset(%Employee{}, emp)
emp_insert = Repo.insert!(emp_c) |> TurnStile.Repo.preload(:organizations)
# embedded schema doesn't exist in DB
** (Postgrex.Error) ERROR 42703 (undefined_column) column o0.owner_employee does not exist

# schema with embeds
schema "organizations" do
    field :email, :string
    field :name, :string
    field :slug, :string
    field :phone, :string
    # org has many employees; employees can belong to many organiztions (mostly for owners)
    many_to_many :employees, Employee, join_through: "organization_employees"
 

    embeds_one :owner_employee, Employee do
      field :first_name, :string
      field :last_name, :string
      field :_email, :string
      field :password, :string, virtual: true, redact: true
    end

schema "employees" do
    field :first_name, :string
    field :last_name, :string
    field :role, :string
    field :email, :string
    field :password, :string, virtual: true, redact: true
    field :confirmed_at, :naive_datetime
    # org has many employees within the company; employees belongs to many orgs
    many_to_many :organizations, Organization, join_through: "organization_employees"

# join table I want to use, but don't know how to use
defmodule Repo.Migrations.OrganizationEmployees do
  use Ecto.Migration

  def change do
    create table(:organization_employees) do
      add :organization_id, references(:organizations)
      add :employee_id, references(:employees)

      timestamps()
    end
    create unique_index(:organization_employees, [:organization_id, :employee_id])

  end
end

First Post!

cevado

cevado

you misunderstood what embedded schemas are. they’re a way to describe a structured jsonb/map field.
if you don´t have a jsonb column named owner_employee you’d be better creating a virtual field(virutal fields are the ones that doesn’t exist in the db) that is a map.

for reference:

Last Post!

cevado

cevado

so, there are a few ways to deal with that:

  • make the field in organizations a virtual one of the type map. being it a map, you can load whatever map you want there, even a employee struct loaded from the database.
  • if there is a query to define which row from employees is a owner_employee you can actually make it a relation… something like
schema "organizations" do
  ...
  has_one :owner_employee, Employee, through: "organization_employees", where: [is_owner: true]
end

and you can preload the owner_employee the same way you preload any other relation.

when you use a embedded schema this way inside another schema is always to describe a structured jsonb field.

Where Next?

Popular in Questions Top

joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
Lily
In templates/appointment/index.html.eex: <%= for appointment <- @appointments do %> <tr> <td><%= appoi...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New

Other popular topics Top

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
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31586 112
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 40165 209
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New

We're in Beta

About us Mission Statement