Open bglusman opened 7 years ago
@praveenperera or @smpallen99 either of you have a minute to discuss/help me think about this in the next day or two?
@bglusman can you post the error please. I'd like to know which module is throwing the error.
Of course! Thanks @smpallen99 ! Here's one of the errors:
Request: GET /admin/credit_type_memberships/new
** (exit) an exception was raised:
** (KeyError) key :id not found in: %OpenPantry.FoodGroup{__meta__: #Ecto.Schema.Metadata<:loaded, "food_groups">, credit_types: #Ecto.Association.NotLoaded<association :credit_types is not loaded>, foodgroup_code: "0100", foodgroup_desc: "Dairy and Egg Products", foods: #Ecto.Association.NotLoaded<association :foods is not loaded>}
(ex_admin) lib/ex_admin/form/fields.ex:32: anonymous fn/5 in ExAdmin.Form.Fields.do_input_collection/8
(elixir) lib/enum.ex:1755: Enum."-reduce/3-lists^foldl/2-0-"/3
(ex_admin) lib/ex_admin/form/fields.ex:30: ExAdmin.Form.Fields.do_input_collection/8
(ex_admin) lib/ex_admin/form.ex:724: anonymous fn/10 in ExAdmin.Form.build_item/5
(ex_admin) lib/ex_admin/themes/admin_lte2.ex:43: ExAdmin.Theme.AdminLte2.wrap_item_type/6
(ex_admin) lib/ex_admin/themes/admin_lte2/form.ex:92: ExAdmin.Theme.AdminLte2.Form.theme_wrap_item/9
(ex_admin) lib/ex_admin/form.ex:612: ExAdmin.Form.wrap_item/9
(ex_admin) lib/ex_admin/form.ex:717: ExAdmin.Form.build_item/5
(ex_admin) lib/ex_admin/form.ex:905: anonymous fn/6 in ExAdmin.Form.build_item/5
(elixir) lib/enum.ex:1755: Enum."-reduce/3-lists^foldl/2-0-"/3
(ex_admin) lib/ex_admin/form.ex:902: anonymous fn/5 in ExAdmin.Form.build_item/5
(ex_admin) lib/ex_admin/themes/admin_lte2/form.ex:145: ExAdmin.Theme.AdminLte2.Form.form_box/3
(ex_admin) lib/ex_admin/form.ex:552: anonymous fn/6 in ExAdmin.Form.build_main_block/4
(elixir) lib/enum.ex:1755: Enum."-reduce/3-lists^foldl/2-0-"/3
(ex_admin) lib/ex_admin/form.ex:550: ExAdmin.Form.build_main_block/4
(ex_admin) lib/ex_admin/themes/admin_lte2/form.ex:24: ExAdmin.Theme.AdminLte2.Form.build_form/6
(ex_admin) web/controllers/admin_resource_controller.ex:73: ExAdmin.AdminResourceController.new/3
(ex_admin) web/controllers/admin_resource_controller.ex:1: ExAdmin.AdminResourceController.action/2
(ex_admin) web/controllers/admin_resource_controller.ex:1: ExAdmin.AdminResourceController.phoenix_controller_pipeline/2
(open_pantry) lib/open_pantry/endpoint.ex:1: OpenPantry.Endpoint.instrument/4
(FWIW, I'm also considering fixing this a few other ways, but though I only currently care about these 2 tables, especially in the admin, there are numerous other tables referencing these foreign keys, and I'd like to make updating to newer versions of this data in the future easy-ish... I started just copying to strings to a new id column and casting to int, which works, but making that the primary key is a little trickier... may keep playing with some version of that though, but I'm not a SQL guru and it's working ok with strings for everything else as is...)
@bglusman Give the following a try in lib/ex_admin/form/fields.ex
def do_input_collection(resource, collection, model_name, field_name, item, %{cardinality: :one, related_key: related_key} = assoc, _params, _errors) do
Adminlog.debug "1st _input_collection... #{field_name}"
ext_name = ext_name model_name, field_name
assoc_fields = get_association_fields(item[:opts])
# err = if errors == [], do: false, else: true
select(class: "form-control", id: "#{ext_name}_id", name: "#{model_name}[#{assoc.owner_key}]") do
handle_prompt(field_name, item)
for item <- collection do
item_id = Map.get(item, related_key)
selected = cond do
Map.get(resource, assoc.owner_key) == item_id ->
[selected: :selected]
# not(params[model_name][Atom.to_string(assoc.owner_key)] in [nil, ""]) ->
# Logger.warn "foo"
# [selected: :selected]
true ->
[]
end
map_relationship_fields(item, assoc_fields)
|> option([value: "#{item_id}"] ++ selected)
end
end
end
Note the changes around releated_key
and item_id
BTW, to figure this stuff out, in iex -S mix, take your model and to this:
OpenPantry.FoodGroup.__schema__(:associations)
to find the associations, then pick the association your interested in and do
OpenPantry.FoodGroup.__schema__(:association, :some_assoc)
and it will list the meta data for the association.
@bglusman I have support for non-standard primary keys in other parts of the code, but must have missed this one.
Thanks Steve! That fixes the proximate cause (running locally via path: "../ex_admin"
with edited fork, so the page renders with a valid belongs_to drop down, but it's not actually setting the relation correctly on form submit now. The one relation with a proper constraint insists the string key is a required field that can't be empty, and the other one I posted before on save errors as so:
ERROR 23502 (not_null_violation): null value in column "food_group_id" violates not-null constraint
Possibly a little confused about the OpenPantry.FoodGroup.__schema__
methods/suggestion, would you like me to pass any of that data on, or did you figure out by cloning and looking at that stuff vs ExAdmin code? Thanks man!
I'm in the process of reviewing a large PR that changes the way ex_admin handles associations and changesets. It takes away some of the ex_admin 'magic' and allows you to control with your own changesets.
I hope to have the PR merged this weekend.
Awesome! Thanks Steve, let me know if I can help in any way!
I've been putting off figuring this out for a few weeks, and though I can partially work around it by making a custom input form that skips the non-standard relationship, I can't figure out if there is a built in way to tell ExAdmin that a particular belongs_to relation (which may be named relation_id) refers to a a table that uses a non-integer primary key not called "id"... it always errors with "key :id not found in", whether building automatically or manually... It seems like ExAdmin needs some ability to reflect on Ecto's @primary_key attribute, or an equivalent option to set on it's modules or relations, but if it exists I can't find it in the source or docs. Hypothetically I'd love to try and contribute this, but I'm not sure my meta-programming skills are up to the task yet :-)
For reference, the code erroring/using the non-standard primary keys is here: https://github.com/MasbiaSoupKitchenNetwork/open_pantry, notably on the stock and credit_type_membership modules relating to food and food_group respectively. Only using this structure so we can use existing USDA food database, so we don't have any control over the keys they use. Otherwise ExAdmin is working out great in the project though, really appreciate all the work!