Angularjs 如何在phoenix中使用嵌套表单关联?

Angularjs 如何在phoenix中使用嵌套表单关联?,angularjs,elixir,phoenix-framework,ecto,Angularjs,Elixir,Phoenix Framework,Ecto,所以我现在正在学习凤凰城1.3,我想学习星外关联。我在前端使用Angularjs 我有两个模式user.ex和profile.ex schema "users" do field(:password_hash, :string) field(:username, :string) # Virtual fields: field(:password, :string, virtual: true) field(:password_confirmation, :string, virtual: tr

所以我现在正在学习凤凰城1.3,我想学习星外关联。我在前端使用Angularjs

我有两个模式user.exprofile.ex

schema "users" do
field(:password_hash, :string)
field(:username, :string)
# Virtual fields:
field(:password, :string, virtual: true)
field(:password_confirmation, :string, virtual: true)
# this was added
has_one(:profiles, AuthApp.Accounts.Profile)

timestamps()end
schema "profiles" do
field :firstname, :string
field :lastname, :string
field :photo, :string
field :user_id, :id
belongs_to :user, AuthApp.Accounts.User  # this was added

timestamps()end
两者均由
mix phx.gen.json生成

user.ex

schema "users" do
field(:password_hash, :string)
field(:username, :string)
# Virtual fields:
field(:password, :string, virtual: true)
field(:password_confirmation, :string, virtual: true)
# this was added
has_one(:profiles, AuthApp.Accounts.Profile)

timestamps()end
schema "profiles" do
field :firstname, :string
field :lastname, :string
field :photo, :string
field :user_id, :id
belongs_to :user, AuthApp.Accounts.User  # this was added

timestamps()end
profile.ex

schema "users" do
field(:password_hash, :string)
field(:username, :string)
# Virtual fields:
field(:password, :string, virtual: true)
field(:password_confirmation, :string, virtual: true)
# this was added
has_one(:profiles, AuthApp.Accounts.Profile)

timestamps()end
schema "profiles" do
field :firstname, :string
field :lastname, :string
field :photo, :string
field :user_id, :id
belongs_to :user, AuthApp.Accounts.User  # this was added

timestamps()end
配置文件控制器

def create(conn, %{"profile" => profile_params}) do
with {:ok, %Profile{} = profile} <- Accounts.create_profile(profile_params) do
  conn
  |> put_status(:created)
  |> put_resp_header("location", profile_path(conn, :show, profile))
  |> render("show.json", profile: profile)
endend
def create(conn,%%{“profile”=>profile_params})do
使用{:确定,%Profile{}=Profile}put_状态(:已创建)
|>放置相应的标题(“位置”,配置文件路径(连接:显示,配置文件))
|>render(“show.json”,profile:profile)
恩登德

我的问题是,我不知道我应该添加什么控制器以及它会是什么样子。

这真的取决于你,你可以用两种方式来做!但是,对于此特定场景,有一些指导/最佳实践风格提示

如果您的应用程序功能/页面/etc主要使用这些域对象之一,请使用该控制器

例如,如果要呈现配置文件页面,并在其中提供各种路由,或加载各种数据块以填充配置文件并启用与其相关的功能,则返回表示数据关系的嵌套API响应对于顶层的配置文件是有意义的

我通常会这样做(从您停止定义的模式和关系的地方开始): 在
ProfileController
中为我的配置文件API请求提取所需的相关数据。我通常通过处理关系预加载的上下文函数来实现这一点。在这种情况下,该组合可能类似于:

def show(conn, %{"id" => id}) do
  profile = Accounts.get_profile!(id)
  render(conn, "show.html", profile: profile)
end
假设类似于
帐户
上下文的内容保存
概要文件
模式, 何处Account.get_profile/1看起来像:

def get_profile!(id) do
  query =
    from(p in Account.Profile,
      where: p.user_id == ^id,
      select: p,
      preload: [:user]
    )

  YourApp.Repo.get(query)
end
profile : {
  photo: {},
  user: {
    id: "1"
  }
}
这最终导致API响应看起来像:

def get_profile!(id) do
  query =
    from(p in Account.Profile,
      where: p.user_id == ^id,
      select: p,
      preload: [:user]
    )

  YourApp.Repo.get(query)
end
profile : {
  photo: {},
  user: {
    id: "1"
  }
}
从启用配置文件功能的角度来看,这是一种直观的方法

但是,有几点需要注意:

  • 我通常通过conn.assigns、session和plug或一些缓存层(如果使用基于令牌的身份验证)将基本用户信息加载到应用程序中。如果你有机会的话,这本书中有很多入门级的例子,卫报图书馆也有很多关于基于令牌的方法的好信息

  • 如果您遵守某个特定的API标准,将会有一些指导原则和最佳实践,所以在Google上搜索“REST”或“GraphQL”,当X将产生有用的见解时

  • 我忽略了有关身份验证/授权等的所有内容,但这样做的好处是(1)可以安全地定义API请求的范围,这样用户就不能只请求与自己不同的配置文件ID(这发生在发出基本配置文件请求并预加载所有用户信息之后)


  • 这真的取决于你,你可以两种方式都做!但是,对于此特定场景,有一些指导/最佳实践风格提示

    如果您的应用程序功能/页面/etc主要使用这些域对象之一,请使用该控制器

    例如,如果要呈现配置文件页面,并在其中提供各种路由,或加载各种数据块以填充配置文件并启用与其相关的功能,则返回表示数据关系的嵌套API响应对于顶层的配置文件是有意义的

    我通常会这样做(从您停止定义的模式和关系的地方开始): 在
    ProfileController
    中为我的配置文件API请求提取所需的相关数据。我通常通过处理关系预加载的上下文函数来实现这一点。在这种情况下,该组合可能类似于:

    def show(conn, %{"id" => id}) do
      profile = Accounts.get_profile!(id)
      render(conn, "show.html", profile: profile)
    end
    
    假设类似于
    帐户
    上下文的内容保存
    概要文件
    模式, 何处Account.get_profile/1看起来像:

    def get_profile!(id) do
      query =
        from(p in Account.Profile,
          where: p.user_id == ^id,
          select: p,
          preload: [:user]
        )
    
      YourApp.Repo.get(query)
    end
    
    profile : {
      photo: {},
      user: {
        id: "1"
      }
    }
    
    这最终导致API响应看起来像:

    def get_profile!(id) do
      query =
        from(p in Account.Profile,
          where: p.user_id == ^id,
          select: p,
          preload: [:user]
        )
    
      YourApp.Repo.get(query)
    end
    
    profile : {
      photo: {},
      user: {
        id: "1"
      }
    }
    
    从启用配置文件功能的角度来看,这是一种直观的方法

    但是,有几点需要注意:

  • 我通常通过conn.assigns、session和plug或一些缓存层(如果使用基于令牌的身份验证)将基本用户信息加载到应用程序中。如果你有机会的话,这本书中有很多入门级的例子,卫报图书馆也有很多关于基于令牌的方法的好信息

  • 如果您遵守某个特定的API标准,将会有一些指导原则和最佳实践,所以在Google上搜索“REST”或“GraphQL”,当X将产生有用的见解时

  • 我忽略了有关身份验证/授权等的所有内容,但这样做的好处是(1)可以安全地定义API请求的范围,这样用户就不能只请求与自己不同的配置文件ID(这发生在发出基本配置文件请求并预加载所有用户信息之后)