Phoenix Elixir发布具有关联的JSON

时间:2018-11-28 19:50:48

标签: elixir phoenix-framework

我想在Phoenix Elixir中发布与JSON的一对多关联。网上有很多例子,但我还没有看到一个具有一对多关联的例子。如何在控制器中传递用于联系的参数?

Costumer的架构为

schema "customers" do
  field :email, :string
  field :name, :string
  has_many :contacts, App.Customers.Contact

  timestamps()
end

@doc false
def changeset(customer, attrs \\ %{}) do
  customer
  |> cast(attrs, [:name, :email])
  |> validate_required([:name, :email])
  |> unique_constraint(:email)
end

Contact的架构为

schema "contacts" do
  field :phone, :string
  belongs_to :customers, App.Customers.Customer,  foreign_key: :customer_id

  timestamps()
end

@doc false
def changeset(contact, attrs \\ %{}) do
  contact
  |> cast(attrs, [:phone])
  |> validate_required([:phone])
end

这是控制器:

def create(conn, %{"email" => email, "name" => name, "phone" => phone} = customer_params) do
  with {:ok, %Customer{} = customer} <- Customers.create_customer(customer_params) do
    conn
    |> put_status(:created)
    |> put_resp_header("location", Routes.customer_path(conn, :show, customer))
    |> render("show.json", customer: customer)
  end
end

1 个答案:

答案 0 :(得分:1)

Customer中,将changeset函数更改为:

def changeset(customer, attrs \\ %{}) do
  customer
  |> cast(attrs, [:name, :email])
  |> validate_required([:name, :email])
  |> unique_constraint(:email)
  |> cast_assoc(:contacts)
end

然后传递这样的参数:

%{"name" => "john doe", "email" => "example@example.com", "contacts" => [
  %{"phone" => "555-555-555"},
  %{"phone" => "555-555-555"}
]}

这样,不需要更改上下文中的create_customer函数:

def create_customer(attrs \\ %{}) do
  %Customer{}
  |> Customer.changeset(attrs)
  |> Repo.insert()
end

但是请记住,为了更新Customer,您需要先预加载联系人。

您可以在cast_assoc documentation中找到更多信息。