evadne / etso

Ecto 3 adapter allowing use of Ecto schemas held in ETS tables
https://hexdocs.pm/etso
Apache License 2.0
377 stars 36 forks source link

Ecto many_to_many Support #9

Closed saifelokour closed 3 years ago

saifelokour commented 4 years ago

This is a minimal test to for a many_to_many relationship. The test is currently failing, and I would love some guidance in how I might proceed. I've created an issue with the details.

evadne commented 3 years ago

This is a very good starting point as discussed via email. I shall investigate

evadne commented 3 years ago

The fundamental issue is that Etso translates where queries to ETS queries and these queries are by nature limited to the table in question.

The many-to-many relationship as currently implemented causes the preloader to issue a single join query which results in the behaviour seen.

A viable workaround for the current version of Etso would be to model the many-to-many relationships straight as multi-level assocs as per this diff…

diff --git a/test/northwind/repo_test.exs b/test/northwind/repo_test.exs
index 9249013..b990191 100644
--- a/test/northwind/repo_test.exs
+++ b/test/northwind/repo_test.exs
@@ -132,6 +132,6 @@ defmodule Northwind.RepoTest do
   test "Employees / Teams / Teams Preload" do
     Model.Employee
     |> Repo.all()
-    |> Repo.preload(:teams)
+    |> Repo.preload(employee_teams: :team)
   end
 end
diff --git a/test/support/northwind/model/employee.ex b/test/support/northwind/model/employee.ex
index 7398367..3908c09 100644
--- a/test/support/northwind/model/employee.ex
+++ b/test/support/northwind/model/employee.ex
@@ -28,10 +28,14 @@ defmodule Northwind.Model.Employee do
     has_many :orders, Model.Order,
       foreign_key: :employee_id,
       references: :employee_id
-
-    many_to_many :teams, Northwind.Model.Team,
-      join_through: Northwind.Model.EmployeeTeam,
-      join_keys: [employee_id: :employee_id, team_id: :team_id]
+    
+    has_many :employee_teams, Model.EmployeeTeam,
+      foreign_key: :employee_id,
+      references: :employee_id
   end

   def changeset(params \\ %{}) do
evadne commented 3 years ago

@saifelokour this is indeed a good way to do it.

evadne commented 3 years ago

Thanks for the change!