Is there a good way to dump params from a controller action?

Hello, I’m trying to add a custom action to a controller.

I pass an ecto record to the controller and am trying to see the content of params which the record is in. I get a some what cryptic error from inspect. I know what going wrong but I can’t help but wonder if there is a php’s equivalent to var_dump.

Here is my custom controller’s action:

   105   def approve(conn, params) do
   106     require Logger
   107     Logger.info("Hello from approve action. Inspectin params content: #{inspect(params)}")
   108   end

Here’s my template:

 53         <%= link "Approve", to: Routes.admin_perfume_approval_path(@conn, :approve, perfume), class: "btn btn-     outline-secondary" %>

And here’s the error:

Protocol.UndefinedError at GET /admin/perfumes_approval
protocol Enumerable not implemented for %Fumigate.Approval.PerfumeApproval{meta: #Ecto.Schema.Metadata<:loaded, "perfume_approvals">, accords: [%Fumigate.Fragrance.Accord{meta: #Ecto.Schema.Metadata<:loaded, "accords">, accord_name: "almond", id: 35, inserted_at: ~N[2019-07-20 19:14:48], perfume_approvals: #Ecto.Association.NotLoaded, perfumes: #Ecto.Association.NotLoaded, updated_at: ~N[2019-07-20 19:14:48]}, %Fumigate.Fragrance.Accord{meta: #Ecto.Schema.Metadata<:loaded, "accords">, accord_name: "animalic", id: 32, inserted_at: ~N[2019-07-20 19:14:48], perfume_approvals: #Ecto.Association.NotLoaded, perfumes: #Ecto.Association.NotLoaded, updated_at: ~N[2019-07-20 19:14:48]}, %Fumigate.Fragrance.Accord{meta: #Ecto.Schema.Metadata<:loaded, "accords">, accord_name: "aromatic", id: 9, inserted_at: ~N[2019-07-20 19:14:48], perfume_approvals: #Ecto.Association.NotLoaded, perfumes: #Ecto.Association.NotLoaded, updated_at: ~N[2019-07-20 19:14:48]}], companies: [], concentration: "hawt", day_released: 3, gender: :men, id: 1, inserted_at: ~N[2019-07-22 07:17:25], month_released: :may, notes: [%Fumigate.Fragrance.Note{meta: #Ecto.Schema.Metadata<:loaded, "notes">, id: 236, inserted_at: ~N[2019-07-20 19:15:38], note_name: "African Orange flower", perfumes: #Ecto.Association.NotLoaded, updated_at: ~N[2019-07-20 19:15:38]}, %Fumigate.Fragrance.Note{meta: #Ecto.Schema.Metadata<:loaded, "notes">, id: 160, inserted_at: ~N[2019-07-20 19:15:38], note_name: "Almond Blossom", perfumes: #Ecto.Association.NotLoaded, updated_at: ~N[2019-07-20 19:15:38]}, %Fumigate.Fragrance.Note{meta: #Ecto.Schema.Metadata<:loaded, "notes">, id: 237, inserted_at: ~N[2019-07-20 19:15:38], note_name: "Amalfi Lemon", perfumes: #Ecto.Association.NotLoaded, updated_at: ~N[2019-07-20 19:15:38]}], perfume_description: "testing perfume approval", perfume_name: "Bot rob", picture_url: "adf", updated_at: ~N[2019-07-24 01:01:23], year_released: 2019}. This protocol is implemented for: Ecto.Adapters.SQL.Stream, Postgrex.Stream, DBConnection.Stream, DBConnection.PrepareStream, Scrivener.Page, HashSet, Range, Map, Function, List, Stream, Date.Range, HashDict, GenEvent.Stream, MapSet, File.Stream, IO.Stream

It took a while but I figure out inspect does not know how to output ecto schema.

Which is fine, I just want to know the structure of my params. What is in it and how it is layout. Kinda like php’s var_dump.

Is there anyway I can do this?

Thanks for your time.

Hi @mythicalprogrammer,

Ecto prevents you from printing out or passing out sensitive information, so it is mandatory to use @derive in your Ecto.Schema and then use that map. That’s the easiest way! Please go through the below links for further understanding…

https://hexdocs.pm/ecto/Ecto.Schema.html#module-schema-attributes

Thanks.

2 Likes

The error you’re showing isn’t because inspect isn’t working. The error you’re getting is about the Enumerable protocol, not the Inspect protocol. I’m not sure where based on the code you’ve shown, but you’re probably treating a %PerfumeApprovol{} as if it’s a list, or passing it to a function that is.

Can you show the full stack trace?

3 Likes

I’ve read your comment and I can do that after I am able to get to my computer.

Thank you.

1 Like

I couldn’t copy paste it… and I’m assuming this is the stack trace you’re talking about.

Thanks again.

I also believe one of the problem is my router.

  65   scope "/admin", FumigateWeb.Admin, as: :admin do
  66     pipe_through [:browser, :protected, :admin_only]
...
  73   resources "/perfumes_approval", PerfumeApprovalController
  74   post "/perfumes_approval", PerfumeController, :approve                                                          
  75   end

I actually figured it out. It’s actually a combination of thing.

The router one where resources always matches, line 73, so line 74 never get to do anything.

Another thing is that edit is magic.

I don’t know how edit does it but it can take ecto stuff without complaining:

Routes.admin_perfume_approval_path(@conn, :edit, perfume)

I’m assuming update does the same thing.

So I’ve decided to fix the router problem by using one of the route/action I’m not using new action instead of creating a custom action, approve. On top of this instead of passing perfume ecto as the third param I pass the record’s id instead:

Routes.admin_perfume_approval_path(@conn, :new, %{ "id" => perfume.id})

Thank you again for your time.

I’m glad you got things working, but I wanted to address this point:

It’s not magic. There’s a protocol for that and Phoenix implements it for structs looking for an :id field. It’ll work in any URL helper, not just edit/update. You can read more here: Phoenix.Param — Phoenix v1.7.10

1 Like