smpallen99 / ex_admin

ExAdmin is an auto administration package for Elixir and the Phoenix Framework
MIT License
1.2k stars 273 forks source link

Nested objects being invalid causes exception - not graceful #228

Open vraravam opened 7 years ago

vraravam commented 7 years ago

I'm trying out the contact_demo repo as the example of this package. In the contact edit screen, when I click on the "Add New Phone number" button (for has_many in a nested form), and then I do not enter any phone number in the text box, but submit the form, this is the error that I get

[debug] module=Phoenix.Logger line=25 function=phoenix_controller_call/3 Processing by ExAdmin.AdminResourceController.update/2
  Parameters: %{"_csrf_token" => "e3M9EBsGOWYoNVUqBy4YHCl8PAwmNgAA72TDR4wWIelFmDLzE6KvLg==", "_method" => "put", "commit" => "Update Contact", "contact" => %{"category_id" => "9", "email" => "zachery.goldner@littel.org", "first_name" => "Adolf", "group_ids" => %{"5" => "on", "6" => "on", "7" => "on"}, "last_name" => "Armstrong", "phone_numbers_attributes" => %{"0" => %{"_destroy" => "0", "id" => "295", "label" => "Home Phone", "number" => "4187106052"}, "1479033341802" => %{"_destroy" => "0", "label" => "Primary Phone", "number" => ""}}}, "id" => "200", "resource" => "contacts", "utf8" => "✓"}
  Pipelines: [:browser]
.....
[error] #PID<0.421.0> running ContactDemo.Endpoint terminated
Server: localhost:4001 (http)
Request: POST /admin/contacts/200
** (exit) an exception was raised:
    ** (Ecto.InvalidChangesetError) could not perform insert because changeset is invalid.

* Changeset changes

%{label: "Primary Phone"}

* Changeset params

%{"_destroy" => "0", "label" => "Primary Phone", "number" => nil}

* Changeset errors

[{"contact[phone_numbers_attributes][1][number]", {"can't be blank", []}}]

        (ecto) lib/ecto/repo/schema.ex:127: Ecto.Repo.Schema.insert!/4
        lib/ex_admin/repo.ex:91: anonymous fn/3 in ExAdmin.Repo.update/1
        (elixir) lib/enum.ex:1623: Enum."-reduce/3-lists^foldl/2-0-"/3
        lib/ex_admin/repo.ex:86: ExAdmin.Repo.update/1
        web/controllers/admin_resource_controller.ex:92: ExAdmin.AdminResourceController.update/3
        web/controllers/admin_resource_controller.ex:1: ExAdmin.AdminResourceController.action/2
        web/controllers/admin_resource_controller.ex:1: ExAdmin.AdminResourceController.phoenix_controller_pipeline/2
        (contact_demo) lib/contact_demo/endpoint.ex:1: ContactDemo.Endpoint.instrument/4
        (contact_demo) lib/phoenix/router.ex:261: ContactDemo.Router.dispatch/2
        (contact_demo) web/router.ex:1: ContactDemo.Router.do_call/2
        (contact_demo) lib/contact_demo/endpoint.ex:1: ContactDemo.Endpoint.phoenix_pipeline/1
        (contact_demo) lib/plug/debugger.ex:123: ContactDemo.Endpoint."call (overridable 3)"/2
        (contact_demo) lib/contact_demo/endpoint.ex:1: ContactDemo.Endpoint.call/2
        (plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4
        (cowboy) src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4
smpallen99 commented 7 years ago

Looks like a valid bug

nathanbuchar commented 7 years ago

Same issue here. In my case, it is required that a DisciplineTitle have an associated discipline_id field, but this is missing when the form is submitted, and the changeset error is thrown indicating that discipline_id must not be blank :(

I should also add that this error occurs regardless of whether :discipline_id is required in the changeset or not.

# This line doesn't need not exist in order to receive the error
|> validate_required(~w(discipline_id)a)

Error:

Ecto.InvalidChangesetError at POST /admin/disciplines could not perform insert because changeset is invalid.

* Changeset changes
%{name: "test"}

* Changeset params
%{"_destroy" => "0", "name" => "test"}

* Changeset errors
[{"discipline[discipline_titles_attributes][0][discipline_id]", {"can't be blank", []}}]

models/discipline.ex

schema "disciplines" do
  field :name, :string
  has_many :discipline_titles, App.DisciplineTitle
end

models/discipline_title.ex

schema "discipline_titles" do
  field :name, :string
  belongs_to :discipline, App.Discipline

  timestamps()
end

admin/discipline.ex

form discipline do
  inputs do
    input discipline, :name
  end

  inputs "Titles" do
    has_many discipline, :discipline_titles, fn(t) ->
      input t, :name
    end
  end
end
nathanbuchar commented 7 years ago

I should note that upon form submission, both the Discipline and the DisciplineTitle are both added to the database, their relationship is working as expected, and they are accessible via the ExAdmin CMS despite the fact that a 500 error is given.

Adding a new discipline and adding a discipline title to go along

screen shot 2017-02-22 at 8 21 38 pm

The form is submitted and an error is received

screen shot 2017-02-22 at 8 24 57 pm

Despite the error, the Discipline was still created

screen shot 2017-02-22 at 8 21 53 pm

Despite the error, the DisciplineTitle was still created

screen shot 2017-02-22 at 8 22 05 pm

Note the correct relationship is in place

screen shot 2017-02-22 at 8 23 22 pm