Search code examples
ruby-on-railsajaxformsujs

How to submit ajax form in Rails 6 with Webpack? Getting ActionController::InvalidAuthenticityToken error


all!

I am following along with the video on GoRails on how to make a chat application using action cable. In the video, I believe Rails 5 is being used, however, I wanted to try it out with Rails 6.

Everything was going great so far. Installed Bootstrap and jQuery and properly configured my environments.js file. It was awesome. Then I get to the part right before we add action cable, and we make the chatroom form remote: true.

I cannot figure out why my form is trying to still submit as HTML instead of JS. On top of that, I am getting an ActionController::InvalidAuthenticityToken error.

Here's how I have my form set up:

<%= simple_form_for [@chatroom, Message.new], remote: true, html: { id: 'message-input' } do |f| %>
  <%= f.input :body, label: false, input_html: { rows: 1, autofocus: true } %>
<% end %>

When I submit, I get this error in my rails server:

Started POST "/chatrooms/1/messages" for ::1 at 2019-10-16 21:02:01 -0500
Processing by MessagesController#create as HTML
  Parameters: {"message"=>{"body"=>"test3"}, "chatroom_id"=>"1"}
Can't verify CSRF token authenticity.
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms | Allocations: 968)



ActionController::InvalidAuthenticityToken - ActionController::InvalidAuthenticityToken:

Started POST "/__better_errors/cf3c4e5c6fa2d1b1/variables" for ::1 at 2019-10-16 21:02:01 -0500

Not sure what to do. I've googled and came across this but I'm not sure if it's entirely applicable: Using Rails-UJS in JS modules (Rails 6 with webpacker)

Any help would be greatly appreciated!


Solution

  • So, it turns out I had to use form_with instead of form_for in order to get it to process as JS. I guess form_for is slowing being deprecated?

    My form now looks like this:

    <%= form_with(model: [@chatroom, Message.new]) do |f| %>
      <%= f.text_field :body %>
    <% end %>
    

    and the output is what I was expecting with out having to submit the CSRF token with JS or skipping the before action in the controller.

    Started POST "/chatrooms/1/messages" for ::1 at 2019-10-18 20:15:14 -0500
    Processing by MessagesController#create as JS
      Parameters: {"authenticity_token"=>"xPBQ+4LOS5aMa7PQ3HEGXAMX6wIIEfQ0Izy/xUqUtleK4mB18IYxC4mOcIoiS5M+FGm6J/WEYMdbM4IVPojScw==", "message"=>{"body"=>"test 5"}, "chatroom_id"=>"1"}
      User Load (0.8ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
      Chatroom Load (0.3ms)  SELECT "chatrooms".* FROM "chatrooms" WHERE "chatrooms"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
      ↳ app/controllers/messages_controller.rb:19:in `set_chatroom'
       (0.1ms)  BEGIN
      ↳ app/controllers/messages_controller.rb:12:in `create'
      Message Create (0.7ms)  INSERT INTO "messages" ("chatroom_id", "user_id", "body", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  [["chatroom_id", 1], ["user_id", 1], ["body", "test 5"], ["created_at", "2019-10-19 01:15:14.619853"], ["updated_at", "2019-10-19 01:15:14.619853"]]
      ↳ app/controllers/messages_controller.rb:12:in `create'
       (5.6ms)  COMMIT
      ↳ app/controllers/messages_controller.rb:12:in `create'
    Redirected to http://localhost:3000/chatrooms/1
    Completed 200 OK in 17ms (ActiveRecord: 7.6ms | Allocations: 4690)