ruby-on-rails - Rails 6 form_with 不会通过 Association 传递资源
问题描述
我正在使用 Rails 6。我有一个需要传递的表单,remote: true
所以我得到 POST 以作为 JS 处理:
LOG: MessagesController#create as JS
这是我尝试过的:
<%= form_for [@hangout, Message.new] do |f| %>
结果很好地保存到数据库,但处理为 HTML:
LOG: MessagesController#create as HTML
所以我尝试了:
<%= form_for [@hangout, Message.new], remote: true do |f| %>
我了解到这会产生 InvalidAuthenticityToken 错误:
LOG: ActionController::InvalidAuthenticityToken - ActionController::InvalidAuthenticityToken:
试过这个:
<%= form_for [@hangout, Message.new], authenticity_token: true do |f| %>
它作为 HTML 传递,而不是 JS
我为 Rails 6 读到过,最好的方法是使用 form_with,因为它通过了remote:true
:
<%= form_with(model: [@hangout, Message.new]) do |f| %>
不幸的是,这永远不会到达控制器,所以我没有得到任何回应。我知道自从第一次尝试使用 form_for 以来我的模型和控制器设置正确,所以它必须与我编写 form_with 的方式一致,对吧?
有人有建议吗?
谢谢!
#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
# application.js
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require('stylesheets/application.scss')
require('jquery')
require("packs/notes")
require("packs/hangouts")
window.Jquery = $;
window.$ = $;
更新
我取得了进展,但并不完全在那里。我使用正确的条目正确地发布到数据库,但没有重定向到 hangouts#show 页面。而是呈现 Create.js.erb:
Form:
<%= form_for [@hangout, Message.new],
remote: true, authenticity_token: true,
format: :js do |f| %>
Controller:
def create
@message = @hangout.messages.build(message_params)
@message.user = current_user
respond_to do |format|
if @message.save
format.js
format.html { redirect_to @hangout, notice: 'Success' }
else
format.html { render action: 'new' }
end
end
end
LOG: Processing by MessagesController#create as JS
但是现在 create.js.erb 在 hangouts#show 应该被渲染时被渲染:
views/messages/create.js.erb
$("#new_message")[0].reset();
Rendered in the browser:
/hangouts/1/messages.js$("#message_body")[0].reset();
任何想法?
解决方案
推荐阅读
- reactjs - 我怎么能不把孩子当道具。相反,在 React 的开始标签和结束标签之间嵌套子元素?
- c# - 如何确定包含不同语言字符的字符串的编码?
- android - 电容器:所有请求都有临时标头
- postgresql - postgres_fdw 扩展没有解释正确的数据类型
- angular - 如何将验证器添加到订阅的自定义输入?
- c - 为什么堆栈中的参数不连续
- angular - 内容投影仅适用于最后一次使用
- apache-camel - 使用骆驼从 RabbitMq 读取消息时,quarkus 开发模式下的 ClassNotFound 异常
- javascript - 用JS改变点击时body的背景颜色
- javascript - 为什么未使用 Multer 目的地