How/where 在 Phoenix 1.3 中预加载 has_many 关系数据
How/where to preload has_many relationship data in Phoenix 1.3
我正在学习 Elixir/Phoenix 示例项目并开始使用 Phoenix 1.2。
现在,我使用 Phoenix 1.3 重新创建了项目以 see/learn 差异并调整我的旧代码。
在那里我有模型 Position
和 Skill
之间的 has_many
关系。而在 position_controller.ex
的 1.2 代码中我使用了
case Repo.insert(changeset) do
{:ok, position} ->
position = position |> Repo.preload(:skills)
...
预加载 skills
以进行渲染 我不确定将它放在我的 1.3 代码中的什么位置。
Controller 现在似乎是错误的地方(Repo
甚至不知道)所以我把它放在 create_position
的上下文文件中,如下所示:
def create_position(attrs \ %{}) do
with {:ok, %Position{} = position} <-
%Position{}
|> Position.changeset(attrs)
|> Repo.insert() do
position = Repo.preload(position, :skills)
{:ok, position}
end
end
这感觉很奇怪,因为它现在不仅仅是插入。
那么执行此任务的正确和最佳方法是什么?
您将希望根据您的上下文/应用程序的外观将内容分开。
def insert_position(attrs) do
attrs
|> changeset()
|> MyApp.Repo.insert()
end
如果技能和职位处于相同的上下文中,您可以按照
的方式做一些事情
def load_skills(position) do
MyApp.Repo.preload(position, :skills)
end
如果是在单独的上下文中,可以进行以下操作
def get_skills_for_position(position) do
# I'm not sure which way you have the relationship
MyApp.Repo.all(from skill in MyApp.Skill,
join: position in MyApp.Position,
on: skill.id == position.skill_id)
end
然后,在你的控制器中,由你来把这些东西放在一起。
def create(conn, %{"position" => position_attrs}) do
case create_position(position_attrs) do
{:ok, position} ->
# or load_skills_for_position, depending if they are in the same contexts.
position = load_skills(position)
...
{:error, changeset} ->
...
end
end
我正在学习 Elixir/Phoenix 示例项目并开始使用 Phoenix 1.2。 现在,我使用 Phoenix 1.3 重新创建了项目以 see/learn 差异并调整我的旧代码。
在那里我有模型 Position
和 Skill
之间的 has_many
关系。而在 position_controller.ex
的 1.2 代码中我使用了
case Repo.insert(changeset) do
{:ok, position} ->
position = position |> Repo.preload(:skills)
...
预加载 skills
以进行渲染 我不确定将它放在我的 1.3 代码中的什么位置。
Controller 现在似乎是错误的地方(Repo
甚至不知道)所以我把它放在 create_position
的上下文文件中,如下所示:
def create_position(attrs \ %{}) do
with {:ok, %Position{} = position} <-
%Position{}
|> Position.changeset(attrs)
|> Repo.insert() do
position = Repo.preload(position, :skills)
{:ok, position}
end
end
这感觉很奇怪,因为它现在不仅仅是插入。
那么执行此任务的正确和最佳方法是什么?
您将希望根据您的上下文/应用程序的外观将内容分开。
def insert_position(attrs) do
attrs
|> changeset()
|> MyApp.Repo.insert()
end
如果技能和职位处于相同的上下文中,您可以按照
的方式做一些事情def load_skills(position) do
MyApp.Repo.preload(position, :skills)
end
如果是在单独的上下文中,可以进行以下操作
def get_skills_for_position(position) do
# I'm not sure which way you have the relationship
MyApp.Repo.all(from skill in MyApp.Skill,
join: position in MyApp.Position,
on: skill.id == position.skill_id)
end
然后,在你的控制器中,由你来把这些东西放在一起。
def create(conn, %{"position" => position_attrs}) do
case create_position(position_attrs) do
{:ok, position} ->
# or load_skills_for_position, depending if they are in the same contexts.
position = load_skills(position)
...
{:error, changeset} ->
...
end
end