【问题标题】:Form data not saving to database on form loaded from different controller / view表单数据未保存到从不同控制器/视图加载的表单上的数据库
【发布时间】:2019-05-07 12:09:35
【问题描述】:

抱歉标题含糊。

我想在 post / cmets 类型系统上启用 cmets(在我的例子中是 snags 和 snag cmets)。

我有一个 snags 表、一个 snag_cmets 表和一个在 snag 和 snag cmets 之间有很多/属于关系的表。

在每个障碍的显示页面上,我都有一个用于障碍 cmets 的表单渲染。当我提交表单时,它会重定向到根 url,并且不会将任何内容保存到 snag_cmets 表中。

这是我得到的所有信息:

于 2019-05-07 12:53:16 +0100 为 ::1 开始 POST "/snag_cmets"
由 SnagCommentsController#create 作为 HTML 处理
  参数:{"utf8"=>"✓", "authenticity_token"=>"yBefFfnI289UXqQYzF37DBRGQSk2Uqu41/OQO/mnET9aj2S3OqjLmSGtgyyZkTDz0aSdKzSPofQNeSzx/UH3ng==", "snag_comment"=>{"snag_id"=>"183", " sdfgfsdgsdfgds"}, "提交"=>"发送"}
  居民负载 (0.3ms) SELECT "residents".* FROM "residents" WHERE "residents"."id" = $1 ORDER BY "residents"."id" ASC LIMIT $2 [["id", 2], ["LIMIT", 1]]
重定向到http://localhost:3000/
过滤器链因 :redirect_residents 呈现或重定向而停止

所以我的参数正在通过。我不知道为什么它没有保存到数据库中。

在我的障碍控制器中,我有:

def show
  @snag_attachments = @snag.snag_attachments.all
  @snag_comment = SnagComment.new
  @snag_comments = SnagComment.where(snag_id: @snag.id)
end

还有我的 snag cmets 控制器(在我弄清楚这个损坏的部分时,它目前不完整):

class SnagCommentsController < ApplicationController
  skip_authorization_check
  before_action :set_parent

  def create
    @snag_comment = SnagComment.new(snag_comment_params)
    if @snag_comment.save
      redirect_to snags_path
    end
  end

  private

  def set_parent
    @parent = @snag
  end

  def snag_comment_params
    params.require(:snag_comment).permit(:content, :image, :snag_id,
                                         :commenter, :first_name, :last_name)
  end
end

呈现的表单(views/snag_cmets/_form):

<div class="snag-comment-form">
  <%= simple_form_for snag_comment, url: snag_comments_path do |f| %>
    <% if snag_comment.errors.any? %>
      <div class="submission-errors">
        <ul>
          <% snag_comment.errors.full_messages.each do |error_msg| %>
            <li>
              <%= fa_icon "exclamation-circle" %>
              <%= error_msg %>
            </li>
          <% end %>
        </ul>
      </div>
    <% end %>

    <%= f.hidden_field :snag_id, value: @snag.id %>
    <%= f.input :content, label: false, as: :text, placeholder: t(".content"), maxlength: 1000, required: true, class: "snag-comment-content" %>

    <div class="snag-comment-submit">
      <%= f.submit t(".send"), class: "btn branded-btn send" %>
    </div>
  <% end %>
</div>

以及从哪里调用表单(views/homeowners/snags/show):

<%= render 'snag_comments/form', snag_comment: @snag_comment %>

我需要将障碍 cmets 置于房主模块之外,因为它还需要可供管理模块访问(管理员和房主可以评论相同的障碍)。

我无法弄清楚为什么表单会重定向而不是保存。我已尝试删除任何重定向并仅指定应保存表单,但它仍重定向到根 url 并且不保存,因此必须在传递参数和实际保存之间编写一些内容。

【问题讨论】:

  • 您是否在config/routes.rb 中声明了root 路由> 如果是,您确定将其放在列表的底部吗?顺序很重要。
  • @parent = @snag 不知道那是什么,但我感觉 skip_authorization_check 无法正常工作,因为我看到“居民”查询然后重定向,看来您授权的 :redirect_residents 部分/authentication 链是一个重定向。也许也发布该代码,因为它似乎与问题非常相关
  • 您应该使用父模型上的关联和 URL 中的 id 参数。做:@parent.comments.new(...)@snag_comments = @snag.comments。不要做SnagComment.new(..., parent_id: 1)SnagComment.where(snag_id: @snag.id)。这与您的重定向问题无关。

标签: ruby-on-rails ruby forms simple-form


【解决方案1】:

您似乎错过了如何设置嵌套资源的最基本基础 - 嵌套路由:

resources :snags do
  resources :snag_comments
end

这将使“父子”关系成为 RESTful 路由的一部分,并且非常清楚发生了什么 VS 在表单正文中隐式传递该信息。

class SnagCommentsController < ApplicationController
  # ...
  before_action :set_snag

  # POST /snags/:snag_id/snag_comments
  def create
    @snag_comment = @snag.comments.new(snag_comment_params)
    if @snag_comment.save
      redirect_to @snag, notice: 'Comment created'
    else
      render :new
    end
  end

  private

  def set_snag
    @snag = Snag.find(params[:snag_id])
  end

  def snag_comment_params
    params.require(:snag_comment)
          .permit(:content, :image,:commenter, :first_name, :last_name)
  end
end

要创建发布到嵌套路由的表单,请使用数组:

def show
  @snag_attachments = @snag.snag_attachments
  @snag_comment = @snag.comments.new
  @snag_comments = @snag.comments
end

<%= simple_form_for([@snag, @snag_comment]) do |f| %>
  # ...
<% end %>

确保删除父 ID 的输入。它在 URL 中作为段显式传递。

【讨论】:

  • 谢谢 :) 。事实证明这是一个路由/控制器问题。我有房主/管理员方面,并试图创建一个他们都可以使用的评论控制器,但它正在重定向,因为房主没有正确的权限。我不得不单独嵌套评论控制器,一个在房主下,一个在管理员下 - 我已经接手了一份已经制作了几年的工作,所以有时弄清楚如何所有工作让我很难过。几个小时盯着这个问题结果是十分钟的解决。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-07
  • 1970-01-01
  • 2021-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多