Hello,
Recently wanted to build a multiple checkbox input form, making it possible to reflect on a many to many association on the modeling.
I am having an error that’s mentioned on the forum previously, and mentioned solution did not work, maybe because, as is, I am not using a put_assoc but cast_assoc instead.
def create(conn, %{"non_gov_org" => non_gov_org_params}) do
non_gov_org_params |> IO.inspect()
case Profiles.create_non_gov_org(non_gov_org_params) do
{:ok, non_gov_org} ->
conn
|> put_flash(:info, "Non gov org created successfully.")
|> redirect(to: Routes.non_gov_org_path(conn, :show, non_gov_org))
{:error, %Ecto.Changeset{} = changeset} ->
changeset |> IO.inspect()
data = Profiles.load_causes(changeset.data)
all_causes = Meta.list_causes()
conn
|> put_flash(:error, "Error!")
|> render("new.html", changeset: %{changeset | data: data}, causes: all_causes)
end
end
Code is entering the :error case below, and IO.inspect is giving the detail for the state of the changeset at that execution.
Here is the inspection output:
#Ecto.Changeset<
action: :insert,
changes: %{
causes: [
#Ecto.Changeset<action: :update, changes: %{}, errors: [],
data: #FutureMadeConcerts.Meta.Cause<>, valid?: true>
],
description: "xsdf",
headquarters: "sdfsdf",
name: "xxxx"
},
errors: [causes: {"is invalid", [validation: :assoc, type: {:array, :map}]}],
data: #FutureMadeConcerts.Profiles.NonGovOrg<>,
valid?: false
>
Here, causes can have multiple non-governmental organisations and vice versa through a third table/schema.
note: They are as follows (cause is generated with schema, NonGovOrg is via html generators.)
#Cause
defmodule FutureMadeConcerts.Meta.Cause do
use Ecto.Schema
import Ecto.Changeset
alias FutureMadeConcerts.Profiles.NonGovOrg
schema "causes" do
field :description, :string
field :image_url, :string
field :info_url, :string
field :name, :string
many_to_many :non_gov_orgs, NonGovOrg,
join_through: "causes_ngos"
timestamps()
end
@doc false
def changeset(cause, attrs) do
cause
|> cast(attrs, [:name, :description, :image_url, :info_url])
|> cast_assoc(:non_gov_orgs, required: false)
|> validate_required([:name, :description, :image_url, :info_url])
end
end
Cause:
defmodule FutureMadeConcerts.Profiles.NonGovOrg do
use Ecto.Schema
import Ecto.Changeset
alias FutureMadeConcerts.Meta.Cause
schema "non_gov_orgs" do
field :description, :string
field :name, :string
field :headquarters, :string
field :image_url, :string
field :website_url, :string
field :number_of_followers, :integer, default: 0
field :number_of_open_projects, :integer, default: 0
many_to_many :causes, Cause,
join_through: "causes_ngos"
timestamps()
end
@doc false
def changeset(non_gov_org, attrs) do
non_gov_org
|> cast(attrs, [:name, :description, :headquarters, :image_url, :website_url])
|> cast_assoc(:causes, required: false)
|> validate_required([:name, :description, :headquarters])
end
end
You can find the code at this repo. It’s a re-write of https://collabomo.de, an app to start and experiment a demand-aware framework.
Bests,
@