HTTP MethodOverride not taking effect

libus[development]> Hanami.app.config.middleware
=> #<Hanami::Slice::Routing::Middleware::Stack:0x00007f7d85c940f0
 @namespaces=[Hanami::Middleware],
 @stack=
  {"/"=>
    [[Warden::Manager, [], {}, #<Proc:0x00007f7d85a695a0 /home/mrimp/workspace/libus/config/app.rb:14>],
     [Hanami::Middleware::BodyParser, [:form], {}, nil],
     [Rack::MethodOverride, [], {}, nil]]}>

With this middleware I have a form

<%= form_for book, "/books/#{id}", method: :patch do %>
  <input name="book[image]" type="hidden" value="<%= book.image_data %>" />
  <input name="book[image] "type="file" />
  <button class="btn btn-primary" type="submit">Submit</button>
<% end %>

Which generates a form:

<form action="/books/3" method="POST" accept-charset="utf-8">
  <input type="hidden" name="_method" value="PATCH">
  <input type="hidden" name="_csrf_token" value="56bff67b47fb16b8a2870a386ca06da59e02eb827e6860c17379efb501c7c643">
  <input name="book[image]" type="hidden" value="">
  <input name="book[image] " type="file">
  <button class="btn btn-primary" type="submit">Submit</button>
</form>

The form helper inputs, csrf and _method are here, so I kinda have no idea where the problem could be, but the errors is:


Hanami::Router::NotAllowedError at /books/3

Only PATCH requests are allowed at /books/3

The route is obviously written as a PATCH, but browsers only understand GET and POST, I saw that Hanami uses the same approach as rails with the rack middleware so I added it but no success.

The form is in slice, but the slice does not have separate config. But is that even relevant? app.config above shows that the middleware is used.

@timriley moved this from chat as discussed.

Relevant code: wip:form not working · krzykamil/libus@141a5b3 · GitHub I added the form and middleware here

I also noticed, that MethodOverride is enabled by default:

lib/hanami/config/actions.rb:89

setting :method_override, default: true

When i run bundle exec hanami middleware I get:

/    Dry::Monitor::Rack::Middleware (instance)
/    Hanami::Middleware::RenderErrors
/    Hanami::Webconsole::Middleware
/    Rack::MethodOverride
/    Rack::Session::Cookie
/    Hanami::Middleware::Assets
/    Warden::Manager
/    Hanami::Middleware::BodyParser
/    Rack::MethodOverride

Listing the MethodOverride twice, cause of my explicit inclusion of the middleware (taking out my explicit setting does not change anything, with just the default, it still does not seem to work).

Thanks for all the details here, Krzysztof!

I’ve just put up a PR with a test that looks to me like it’s showing rack method overrides working as expected: Add test for rack method overrides by timriley · Pull Request #1380 · hanami/hanami · GitHub

If you’re seeing different results in your app, then I must be missing something. Is there something else happening in your branch that I might be missing in my (admittedly contrived) test example?

What is weird, is that the request goes through the middleware, MethodOverride receives call as seen in the error stack trace.

I’m thinking some other middleware is inferring with it, but as of now no idea what.

I’ll update the thread once I figure it out, if it does not seem broken in the framework itself then I can sleep safely :slight_smile:

Found the solution, and the problem was actually with the form, although it is quite subtle.

The form sends a file, but was missing:

enctype: "multipart/form-data"

form_for helper does not know automatically to add that based on the input inside of it, it had to be explicit.

As for why the error was confusing:

#lib/rack/request.rb:452

set_header RACK_REQUEST_FORM_HASH, parse_query(form_vars, '&')

Was throwing Invalid or incomplete POST params because it was unable to parse the params, since they were not formatted correctly (due to the missing enctype). The error (Utils::ParameterTypeError) was rescued at rack/method_override.rb.

I checked out the form helper from
lib/hanami/helpers/form_helper.rb

But didn’t see any documentation there about using file inputs and since I mostly use simple_form and rails form helpers for building forms and they add the enctype automatically I guess I assumed this did too. My mistake.

Hope this helps someone :stuck_out_tongue:

Excellent sleuthing, @krzykamil! Thanks for the follow-up.

That’s certainly a very misleading error condition and, if possible, I’d like to make sure we don’t have users encounter it.

What were you using to output the file field for the form? Hanami does provide a file_field helper that sets the form’s enctype to "multipart/form-data" (and we have a test for this, too). If you were using that helper, then the experience you encountered was definitely a bug. Can you please let me know?

Update: I just realised from your initial code snippet that you weren’t using the file_field helper. If you update your form_for invocation to yield the form, you can then use e.g. f.file_field "book.image" and you should be good to go.

Ok, so I guess my mistake was just not using the helpers. I did not see them in the Hanami Guides and haven’t looked hard enough in the source code to find those so I used regular html inputs.

Using what you linked, does generate valid html, and the request is parsed correctly. Thanks for your input and sorry for misleading issue case :slight_smile: