Elixir Phoenix:在许多关系中保存重复记录

时间:2018-03-14 18:18:52

标签: elixir ecto

我正在开发一个bulksms网络应用。我为小组和联系人创建了许多关系,我也编写了一个函数,但我注意到每次提交表单以创建新组时,联系人都会在联系人表中保存为重复项,而不检查联系人是否存在或不。

defmodule Smsdial.ContactManager.Group do
  use Ecto.Schema
  import Ecto.Changeset
  import Ecto.Query, warn: false
  alias Smsdial.Repo
  alias Smsdial.ContactManager.Group
  alias Smsdial.ContactManager.Contact


  schema "groups" do
    field :description, :string
    field :name, :string
    field :contacts, :string
    #field :user_id, :id
    many_to_many :contact, Smsdial.ContactManager.Contact, join_through: 
    Smsdial.ContactManager.Contact_Group
    belongs_to :user, Smsdial.Coherence.User

    timestamps()
  end

  # many-many relationship

  def changeset(%Group{} = group, attr) do
    group
    |> cast(attr, [:name, :description, :contacts])
    |> validate_required([:name])
    |> Ecto.Changeset.put_assoc(:contact, parse_contact(attr))
  end

  defp parse_contact(attr)  do
    (attr["contacts"] || "")
    |> String.split(",")
    |> Enum.map(&String.trim/1)
    |> Enum.reject(& &1 == "")
    |> insert_and_get_all()
  end

  defp insert_and_get_all([]) do
    []
  end

  defp insert_and_get_all(phones) do
    maps = Enum.map(phones, &%{phone: &1, inserted_at: DateTime.utc_now, 
    updated_at: DateTime.utc_now})
      for c <- maps do
        if c.phone == @contact.phone do
          :contact_already_exist
        else 
          Repo.insert_all Contact, maps, on_conflict: :nothing
          Repo.all(from t in Contact, where: t.phone in ^phones)
      end
  end    
 end 
end

这是我的代码片段。也许我可以得到关于如何在联系人和群组之间建立关系的任何建议,当我创建一个包含联系人的群组时,联系人应该直接保存到联系人表中,如果之前存在联系人号码则标记错误。

谢谢

0 个答案:

没有答案