如何/在哪里预加载Phoenix 1.3中的has_many关系数据

时间:2017-09-17 15:37:20

标签: elixir phoenix-framework ecto

我在一个示例项目中学习Elixir / Phoenix,并开始使用Phoenix 1.2。 现在,我使用Phoenix 1.3重新创建项目,以查看/了解差异并调整我的旧代码。

在那里,我在模型has_manyPosition之间存在Skill关系。而position_controller.ex中的1.2代码中我使用了

case Repo.insert(changeset) do
  {:ok, position} ->
    position = position |> Repo.preload(:skills)
    ...

预先加载skills进行渲染我不确定将其放在我的1.3代码中的哪个位置。

控制器现在似乎是错误的地方(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

这感觉很奇怪,因为它现在不仅仅是插入。

那么执行此任务的正确和最佳方法是什么?

1 个答案:

答案 0 :(得分:3)

您需要根据上下文/应用程序的外观将内容分开。

- name:               Get Radar exe url
  shell:              curl -s https://api.github.com/repos/Radarr/Radarr/releases | grep linux.tar.gz | grep browser_download_url | head -1 | cut -d \" -f 4
  register:           shell_output
- set_fact:
    Radarr_exe_url : "{{ shell_output.stdout }}"

如果技能和职位处于相同的背景下,你可以按照

的方式做点什么
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