Ask A Question

Notifications

You’re not receiving notifications from this thread.

Rails 6 form_with will not pass resources with Association

Jim Miller asked in Rails

I am using Rails 6. I have a form that I need to pass remote: true so I get POST to process as JS:

LOG: MessagesController#create as JS

Here is what I have tried:

<%= form_for [@hangout, Message.new] do |f| %>

The result is a good save to the DB but processes as HTML:

LOG: MessagesController#create as HTML

So I tried:

<%= form_for [@hangout, Message.new], remote: true do |f| %>

I learned that this would give an InvalidAuthenticityToken error:

LOG: ActionController::InvalidAuthenticityToken - ActionController::InvalidAuthenticityToken:

Tried this:

<%= form_for [@hangout, Message.new], authenticity_token: true do |f| %>

It passes as HTML, not JS

I read that for Rails 6, the best way to do this was with form_with because it passes remote:true:

<%= form_with(model: [@hangout, Message.new]) do |f| %>

Unfortunately, this never reaches the controller so I get no response. I know that my model and controller are set up properly since the first try with form_for works, so it has to be with the way I am writing my form_with, right?

Does anyone have any advice?

Thanks!

#model
class Message < ApplicationRecord
  belongs_to :hangout
  belongs_to :user
end

#controller
class MessagesController < ApplicationController
  before_action :authenticate_user!
  before_action :set_hangout
  def create
    message = @hangout.messages.new(message_params)
    message.user = current_user
    message.save
    redirect_to @hangout
  end
  private
    def set_hangout
      @hangout = Hangout.find(params[:hangout_id])
    end
    def message_params
      params.require(:message).permit(:body)
    end
end

#routes
require 'sidekiq/web'

Rails.application.routes.draw do
  resources :hangouts do
    resource :hangout_users
    resources :messages
  end

  resources :notes

  authenticate :user, lambda { |u| u.admin? } do
    mount Sidekiq::Web => '/sidekiq'
  end

  devise_for :users, controllers: { registrations: 'users/registrations' }

  get 'mine', to: 'notes#mine'

  root to: 'application#root'

  mount Shrine.presign_endpoint(:cache) => '/images/upload'
end
Reply

BTW, I am working on this Lesson:
Group Chat with ActionCable: Part 3

Reply

Updated my controller but still no go:

def create
  message = @hangout.messages.new(message_params)
  message.user = current_user
  respond_to do |format|
    if message.save
      format.html { redirect_to @hangout, notice: 'Success' }
      format.js
    else
      format.html { render action: 'new' }
  end
end
Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 87,110+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.