【问题标题】:Building association between two tables before inserting在插入之前在两个表之间建立关联
【发布时间】:2019-10-18 17:39:27
【问题描述】:

我有表 user_profile 和 roles。在 user_profile 引用角色表中有一个外键列 roles_id。 在将数据插入 user_profile 表之前,我必须在两个表之间建立关联。

我正在尝试使用 Ecto.Multi.merge 执行此操作,但存在一些错误。它不工作。而且我不知道我在哪里犯了错误。 据我说, Ecto.Multi.merge 函数采用从函数返回的多对象。 直接传递函数不起作用。

 def create_user_profile(profile_info, dealer_id) do
    import Sage
    client_id = Map.get(profile_info, "client_id")
    type = Map.get(profile_info, "user_type")
    role_name = Map.get(profile_info, "role_name")
    role_struct = Repo.get_by(Roles, role_name: role_name)

    Ecto.Multi.merge(Repo.get_by(Roles, role_name: role_name), fn %{role: role}->
    user_role = Ecto.build_assoc(role, :user_profile)|> UserProfile.changeset(profile_info)
    Ecto.Multi.new()
    |> Ecto.Multi.insert(:user_role, user_role)end)
    |> Ecto.Multi.merge(fn %{user: user} ->
      bank_detail =
        Ecto.build_assoc(user, :bank_details)
        |> BankDetails.changeset(profile_info)

      Ecto.Multi.new()
      |> Ecto.Multi.insert(:bank_detail, bank_detail)
    end)

这是一个sn-p的代码。请帮我。我是这种语言的新手

每当我尝试使用邮递员运行时...都会显示此错误

(FunctionClauseError) no function clause matching in Ecto.Multi.merge/2
        (ecto) lib/ecto/multi.ex:228: Ecto.Multi.merge(%Accreditor.Role.Roles{__meta__: #Ecto.Schema.Metadata<:loaded, "roles">, id: 1, inserted_at: ~N[2019-05-31 07:21:21], permissions: #Ecto.Association.NotLoaded<association :permissions is not loaded>, role_name: "SUPER", updated_at: ~N[2019-05-31 07:21:21], user_profile: #Ecto.Association.NotLoaded<association :user_profile is not loaded>, user_type: #Ecto.Association.NotLoaded<association :user_type is not loaded>, user_type_id: 1}, #Function<3.131196970/1 in Accreditor.Accounts.create_user_profile/2>)
        (accreditor) lib/core/accounts/accounts.ex:224: Accreditor.Accounts.create_user_profile/2
        (accreditor) lib/core/accounts/accounts.ex:195: Accreditor.Accounts.create_account/2
        (accreditor) lib/web/controllers/user_controller.ex:17: AccreditorWeb.UserController.create_user/2
        (accreditor) lib/web/controllers/user_controller.ex:1: AccreditorWeb.UserController.action/2
        (accreditor) lib/web/controllers/user_controller.ex:1: AccreditorWeb.UserController.phoenix_controller_pipeline/2
        (primus_web) lib/primus_web/endpoint.ex:1: PrimusWeb.Endpoint.instrument/4
        (phoenix) lib/phoenix/router.ex:275: Phoenix.Router.__call__/1
        (phoenix) lib/phoenix/router/route.ex:39: Phoenix.Router.Route.call/2
        (phoenix) lib/phoenix/router.ex:275: Phoenix.Router.__call__/1
        (primus_web) lib/primus_web/endpoint.ex:1: PrimusWeb.Endpoint.plug_builder_call/2
        (primus_web) lib/plug/debugger.ex:122: PrimusWeb.Endpoint."call (overridable 3)"/2
        (primus_web) lib/primus_web/endpoint.ex:1: PrimusWeb.Endpoint.call/2
        (phoenix) lib/phoenix/endpoint/cowboy2_handler.ex:33: Phoenix.Endpoint.Cowboy2Handler.init/2

【问题讨论】:

  • 请格式化代码以使其可读发布完整的错误消息。
  • 你现在能查一下吗

标签: elixir phoenix-framework ecto


【解决方案1】:

从错误消息中可以看出,Repo.get_by/2 返回 %Accreditor.Role.Roles{} 结构,它没有 role 字段。而您正试图将它传递给函数,该函数接受一个要在 %{role: role} 上进行模式匹配的参数,这显然失败了。

Ecto.Multi.merge(%Accreditor.Role.Roles{
  __meta__: #Ecto.Schema.Metadata<:loaded, "roles">,
  id: 1,
  inserted_at: ~N[2019-05-31 07:21:21],
  permissions: #Ecto.Association.NotLoaded<[...]>,
  role_name: "SUPER",
  updated_at: ~N[2019-05-31 07:21:21],
  user_profile: #Ecto.Association.NotLoaded<[...]>,
  user_type: #Ecto.Association.NotLoaded<[...]>,
  user_type_id: 1}, #Function[...]}

你还没有发布你的架构,所以我只能猜测你的 Roles 架构有办法到达 role,有点像

roles = Repo.get_by(Roles, role_name: role_name)
Ecto.Multi.merge(get_role(roles), fn role -> ... end)

会解决问题。

【讨论】:

  • elixir roles = Repo.get_by(Roles, role_name: role_name) 将返回一个包含 role_name 的结构。为什么要在elixir Ecto.Multi.merge() 中写另一个函数elixir get_role
  • 我不确定我是否遵循。如果您需要role_name,只需使用fn %{role_name: role_name} -&gt; 或任何与Repo.get_by/2 的结果真正匹配的函数更新您的函数。
猜你喜欢
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 2011-10-10
  • 1970-01-01
  • 1970-01-01
  • 2020-01-01
  • 1970-01-01
  • 2020-01-17
相关资源
最近更新 更多