为 many_to_many 关联创建可组合查询
Create composable query for many_to_many association
我正在尝试创建一个可组合的 ecto 查询,以列出特定 Contributor
的所有 Document
。我希望 api 看起来像这样:
Document
|> Document.for_contributor(contributor)
|> Repo.all()
但我不知道从哪里开始。我之前和在 has_many
关系中一直在进行可组合查询,其中 Contributor
可能有很多 Document
我会做这样的事情:
def for_contributor(query, %Contributor{} = contributor) do
from(document in query, where: document.contributor_id == ^contributor.id)
end
但我不确定我将如何着手做类似但具有 many_to_many
关系的事情。
我的 for_contributor
函数中会包含什么?
defmodule MyApp.Document do
use Ecto.Schema
import Ecto.Changeset
alias MyApp.Contributor
schema "documents" do
many_to_many(:contributors, Contributor, join_through: "contributors_documents")
timestamps()
end
def for_contributor(query, %Contributor{} = contributor) do
# ???
end
end
我的加入 table 看起来像这样:
defmodule MyApp.Repo.Migrations.CreateContributorsDocuments do
use Ecto.Migration
def change do
create table(:contributors_documents, primary_key: false) do
add :contributor_id, references(:contributors)
add :document_id, references(:documents)
end
end
end
我把它想得比需要的更复杂。我用一个简单的 join
.
解决了它
def for_contributor(query, %Contributor{} = contributor) do
from(
document in query,
join: c in assoc(document, :contributors),
where: c.id == ^contributor.id
)
end
我正在尝试创建一个可组合的 ecto 查询,以列出特定 Contributor
的所有 Document
。我希望 api 看起来像这样:
Document
|> Document.for_contributor(contributor)
|> Repo.all()
但我不知道从哪里开始。我之前和在 has_many
关系中一直在进行可组合查询,其中 Contributor
可能有很多 Document
我会做这样的事情:
def for_contributor(query, %Contributor{} = contributor) do
from(document in query, where: document.contributor_id == ^contributor.id)
end
但我不确定我将如何着手做类似但具有 many_to_many
关系的事情。
我的 for_contributor
函数中会包含什么?
defmodule MyApp.Document do
use Ecto.Schema
import Ecto.Changeset
alias MyApp.Contributor
schema "documents" do
many_to_many(:contributors, Contributor, join_through: "contributors_documents")
timestamps()
end
def for_contributor(query, %Contributor{} = contributor) do
# ???
end
end
我的加入 table 看起来像这样:
defmodule MyApp.Repo.Migrations.CreateContributorsDocuments do
use Ecto.Migration
def change do
create table(:contributors_documents, primary_key: false) do
add :contributor_id, references(:contributors)
add :document_id, references(:documents)
end
end
end
我把它想得比需要的更复杂。我用一个简单的 join
.
def for_contributor(query, %Contributor{} = contributor) do
from(
document in query,
join: c in assoc(document, :contributors),
where: c.id == ^contributor.id
)
end