Phoenix Elixir Post JSON with association
I want to POST for association one to many with JSON in Phoenix Elixir. There are many examples on the web, but I have not seen one example with one to many association. How can I pass the parameters for contact in the controller?
The schema for Costumer
is
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
The schema for Contact
is
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
This is the controller:
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
elixir phoenix-framework
add a comment |
I want to POST for association one to many with JSON in Phoenix Elixir. There are many examples on the web, but I have not seen one example with one to many association. How can I pass the parameters for contact in the controller?
The schema for Costumer
is
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
The schema for Contact
is
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
This is the controller:
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
elixir phoenix-framework
Are you having an issue with Ecto and the associations, or is your issue with how to get the JSON params?
– Justin Wood
Nov 28 '18 at 20:20
I think both, in the contextual module I have: def create_customer(attrs \ %{}) do %Customer{} |> Customer.changeset(attrs) |> Ecto.Changeset.cast_assoc(:contacts, with: &Contact.changeset/2) |> Repo.insert() end
– parmalat22
Nov 28 '18 at 20:32
add a comment |
I want to POST for association one to many with JSON in Phoenix Elixir. There are many examples on the web, but I have not seen one example with one to many association. How can I pass the parameters for contact in the controller?
The schema for Costumer
is
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
The schema for Contact
is
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
This is the controller:
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
elixir phoenix-framework
I want to POST for association one to many with JSON in Phoenix Elixir. There are many examples on the web, but I have not seen one example with one to many association. How can I pass the parameters for contact in the controller?
The schema for Costumer
is
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
The schema for Contact
is
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
This is the controller:
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
elixir phoenix-framework
elixir phoenix-framework
edited Nov 28 '18 at 23:33
Gabriel Prá
1,049617
1,049617
asked Nov 28 '18 at 19:50
parmalat22parmalat22
135
135
Are you having an issue with Ecto and the associations, or is your issue with how to get the JSON params?
– Justin Wood
Nov 28 '18 at 20:20
I think both, in the contextual module I have: def create_customer(attrs \ %{}) do %Customer{} |> Customer.changeset(attrs) |> Ecto.Changeset.cast_assoc(:contacts, with: &Contact.changeset/2) |> Repo.insert() end
– parmalat22
Nov 28 '18 at 20:32
add a comment |
Are you having an issue with Ecto and the associations, or is your issue with how to get the JSON params?
– Justin Wood
Nov 28 '18 at 20:20
I think both, in the contextual module I have: def create_customer(attrs \ %{}) do %Customer{} |> Customer.changeset(attrs) |> Ecto.Changeset.cast_assoc(:contacts, with: &Contact.changeset/2) |> Repo.insert() end
– parmalat22
Nov 28 '18 at 20:32
Are you having an issue with Ecto and the associations, or is your issue with how to get the JSON params?
– Justin Wood
Nov 28 '18 at 20:20
Are you having an issue with Ecto and the associations, or is your issue with how to get the JSON params?
– Justin Wood
Nov 28 '18 at 20:20
I think both, in the contextual module I have: def create_customer(attrs \ %{}) do %Customer{} |> Customer.changeset(attrs) |> Ecto.Changeset.cast_assoc(:contacts, with: &Contact.changeset/2) |> Repo.insert() end
– parmalat22
Nov 28 '18 at 20:32
I think both, in the contextual module I have: def create_customer(attrs \ %{}) do %Customer{} |> Customer.changeset(attrs) |> Ecto.Changeset.cast_assoc(:contacts, with: &Contact.changeset/2) |> Repo.insert() end
– parmalat22
Nov 28 '18 at 20:32
add a comment |
1 Answer
1
active
oldest
votes
In Customer
, change the changeset
function to:
def changeset(customer, attrs \ %{}) do
customer
|> cast(attrs, [:name, :email])
|> validate_required([:name, :email])
|> unique_constraint(:email)
|> cast_assoc(:contacts)
end
And then pass the parameters like this:
%{"name" => "john doe", "email" => "example@example.com", "contacts" => [
%{"phone" => "555-555-555"},
%{"phone" => "555-555-555"}
]}
With this, the create_customer
function in the context doesn't need to be changed:
def create_customer(attrs \ %{}) do
%Customer{}
|> Customer.changeset(attrs)
|> Repo.insert()
end
Keep in mind, though, that in order to update a Customer
, you would need to first preload contacts.
You can find more information in the cast_assoc documentation.
thanks, but I have the error no function clause matching in AppWeb.CustomerController.create/2 . # 1 %Plug.Conn{adapter: {Plug.Cowboy.Conn, :...}, assigns: %{}, before_send: [#Function<1.112466771/1 in Plug.Logger.call/2> . # 2 %{"email" => "l", "name" => "l", "phone" => "9"}
– parmalat22
Nov 30 '18 at 19:36
You can remove the pattern matching in yourAppWeb.CustomerController.create/2
definition:def create(conn, customer_params) do ....
.
– Gabriel Prá
Nov 30 '18 at 23:40
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53527071%2fphoenix-elixir-post-json-with-association%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
In Customer
, change the changeset
function to:
def changeset(customer, attrs \ %{}) do
customer
|> cast(attrs, [:name, :email])
|> validate_required([:name, :email])
|> unique_constraint(:email)
|> cast_assoc(:contacts)
end
And then pass the parameters like this:
%{"name" => "john doe", "email" => "example@example.com", "contacts" => [
%{"phone" => "555-555-555"},
%{"phone" => "555-555-555"}
]}
With this, the create_customer
function in the context doesn't need to be changed:
def create_customer(attrs \ %{}) do
%Customer{}
|> Customer.changeset(attrs)
|> Repo.insert()
end
Keep in mind, though, that in order to update a Customer
, you would need to first preload contacts.
You can find more information in the cast_assoc documentation.
thanks, but I have the error no function clause matching in AppWeb.CustomerController.create/2 . # 1 %Plug.Conn{adapter: {Plug.Cowboy.Conn, :...}, assigns: %{}, before_send: [#Function<1.112466771/1 in Plug.Logger.call/2> . # 2 %{"email" => "l", "name" => "l", "phone" => "9"}
– parmalat22
Nov 30 '18 at 19:36
You can remove the pattern matching in yourAppWeb.CustomerController.create/2
definition:def create(conn, customer_params) do ....
.
– Gabriel Prá
Nov 30 '18 at 23:40
add a comment |
In Customer
, change the changeset
function to:
def changeset(customer, attrs \ %{}) do
customer
|> cast(attrs, [:name, :email])
|> validate_required([:name, :email])
|> unique_constraint(:email)
|> cast_assoc(:contacts)
end
And then pass the parameters like this:
%{"name" => "john doe", "email" => "example@example.com", "contacts" => [
%{"phone" => "555-555-555"},
%{"phone" => "555-555-555"}
]}
With this, the create_customer
function in the context doesn't need to be changed:
def create_customer(attrs \ %{}) do
%Customer{}
|> Customer.changeset(attrs)
|> Repo.insert()
end
Keep in mind, though, that in order to update a Customer
, you would need to first preload contacts.
You can find more information in the cast_assoc documentation.
thanks, but I have the error no function clause matching in AppWeb.CustomerController.create/2 . # 1 %Plug.Conn{adapter: {Plug.Cowboy.Conn, :...}, assigns: %{}, before_send: [#Function<1.112466771/1 in Plug.Logger.call/2> . # 2 %{"email" => "l", "name" => "l", "phone" => "9"}
– parmalat22
Nov 30 '18 at 19:36
You can remove the pattern matching in yourAppWeb.CustomerController.create/2
definition:def create(conn, customer_params) do ....
.
– Gabriel Prá
Nov 30 '18 at 23:40
add a comment |
In Customer
, change the changeset
function to:
def changeset(customer, attrs \ %{}) do
customer
|> cast(attrs, [:name, :email])
|> validate_required([:name, :email])
|> unique_constraint(:email)
|> cast_assoc(:contacts)
end
And then pass the parameters like this:
%{"name" => "john doe", "email" => "example@example.com", "contacts" => [
%{"phone" => "555-555-555"},
%{"phone" => "555-555-555"}
]}
With this, the create_customer
function in the context doesn't need to be changed:
def create_customer(attrs \ %{}) do
%Customer{}
|> Customer.changeset(attrs)
|> Repo.insert()
end
Keep in mind, though, that in order to update a Customer
, you would need to first preload contacts.
You can find more information in the cast_assoc documentation.
In Customer
, change the changeset
function to:
def changeset(customer, attrs \ %{}) do
customer
|> cast(attrs, [:name, :email])
|> validate_required([:name, :email])
|> unique_constraint(:email)
|> cast_assoc(:contacts)
end
And then pass the parameters like this:
%{"name" => "john doe", "email" => "example@example.com", "contacts" => [
%{"phone" => "555-555-555"},
%{"phone" => "555-555-555"}
]}
With this, the create_customer
function in the context doesn't need to be changed:
def create_customer(attrs \ %{}) do
%Customer{}
|> Customer.changeset(attrs)
|> Repo.insert()
end
Keep in mind, though, that in order to update a Customer
, you would need to first preload contacts.
You can find more information in the cast_assoc documentation.
answered Nov 28 '18 at 21:24
Gabriel PráGabriel Prá
1,049617
1,049617
thanks, but I have the error no function clause matching in AppWeb.CustomerController.create/2 . # 1 %Plug.Conn{adapter: {Plug.Cowboy.Conn, :...}, assigns: %{}, before_send: [#Function<1.112466771/1 in Plug.Logger.call/2> . # 2 %{"email" => "l", "name" => "l", "phone" => "9"}
– parmalat22
Nov 30 '18 at 19:36
You can remove the pattern matching in yourAppWeb.CustomerController.create/2
definition:def create(conn, customer_params) do ....
.
– Gabriel Prá
Nov 30 '18 at 23:40
add a comment |
thanks, but I have the error no function clause matching in AppWeb.CustomerController.create/2 . # 1 %Plug.Conn{adapter: {Plug.Cowboy.Conn, :...}, assigns: %{}, before_send: [#Function<1.112466771/1 in Plug.Logger.call/2> . # 2 %{"email" => "l", "name" => "l", "phone" => "9"}
– parmalat22
Nov 30 '18 at 19:36
You can remove the pattern matching in yourAppWeb.CustomerController.create/2
definition:def create(conn, customer_params) do ....
.
– Gabriel Prá
Nov 30 '18 at 23:40
thanks, but I have the error no function clause matching in AppWeb.CustomerController.create/2 . # 1 %Plug.Conn{adapter: {Plug.Cowboy.Conn, :...}, assigns: %{}, before_send: [#Function<1.112466771/1 in Plug.Logger.call/2> . # 2 %{"email" => "l", "name" => "l", "phone" => "9"}
– parmalat22
Nov 30 '18 at 19:36
thanks, but I have the error no function clause matching in AppWeb.CustomerController.create/2 . # 1 %Plug.Conn{adapter: {Plug.Cowboy.Conn, :...}, assigns: %{}, before_send: [#Function<1.112466771/1 in Plug.Logger.call/2> . # 2 %{"email" => "l", "name" => "l", "phone" => "9"}
– parmalat22
Nov 30 '18 at 19:36
You can remove the pattern matching in your
AppWeb.CustomerController.create/2
definition: def create(conn, customer_params) do ....
.– Gabriel Prá
Nov 30 '18 at 23:40
You can remove the pattern matching in your
AppWeb.CustomerController.create/2
definition: def create(conn, customer_params) do ....
.– Gabriel Prá
Nov 30 '18 at 23:40
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53527071%2fphoenix-elixir-post-json-with-association%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Are you having an issue with Ecto and the associations, or is your issue with how to get the JSON params?
– Justin Wood
Nov 28 '18 at 20:20
I think both, in the contextual module I have: def create_customer(attrs \ %{}) do %Customer{} |> Customer.changeset(attrs) |> Ecto.Changeset.cast_assoc(:contacts, with: &Contact.changeset/2) |> Repo.insert() end
– parmalat22
Nov 28 '18 at 20:32