【问题标题】:Nested Form not rendering or saving data嵌套表单不呈现或保存数据
【发布时间】:2016-07-28 02:11:03
【问题描述】:

我是 Ruby 和 Rails 的新手,我正在尝试组合一个嵌套表单,最终创建一个页面,但也允许用户在提交页面之前创建单独的部分内联 .内联表单包含两个按钮,一个添加一个部分,另一个删除它。这是我的相关文件(如果您需要查看其他文件,请告诉我),我将列出我遇到的问题:

仅供参考,我使用的 gem 是:SlimSimple Formcocoon 和 Bootstrap。在 Rails 4 上。

_form.html.slim

= simple_form_for(@page, html: { class: 'form-horizontal' }) do |f|

  = f.input :title, label: 'Title'
  = f.input :description, label: 'Desc'

  .form-group
    .col-xs-10
      label Parts
      .form-inline
        = f.simple_fields_for :parts do |part|
          = render 'part_fields', f: part
        .links
          = link_to_add_association 'Add Part', f, :parts

  = f.button :submit

_parts_fields.html.slim

= f.input :part_type, collection: ['String 1', 'String 2'], prompt: 'Part type', label: false
= f.input :part_title, placeholder: 'Part title', label: false
= f.input :part_desc, placeholder: 'Part description', label: false
= link_to_remove_association 'Remove Part', f

/models/page.rb

class Page < ActiveRecord::Base
    belongs_to :project
    has_many :parts
    accepts_nested_attributes_for :parts
end

/models/part.rb

class Part < ActiveRecord::Base
    belongs_to :page
end

/controllers/pages_controller.rb

class PagesController < ApplicationController
    def index
        @pages = Page.all

        respond_to do |format|
            format.html 
            format.json { render json: @pages }
        end
    end

    def new
        @page = Page.new

        respond_to do |format|
            format.html 
            format.json { render json: @page }
        end
    end

    def edit
        @page = Page.find(params['id'])
    end

    def create
    @page = Page.new(page_params)

        respond_to do |format|
            if @page.save
                format.html { redirect_to(@page) }
                format.json { render json: @page, status: :created, location: @page }
            else
                format.html { render action: 'new' }
                format.json { render json: @page.errors, status: :unprocessable_entity }
            end
        end
  end

  def update
    @page = Page.find(params['id'])

        respond_to do |format|
            if @page.update_attributes(page_params)
                format.html { redirect_to(action: 'index') }
                format.json { head :ok }
            else
                format.html { render action: 'edit' }
                format.json { render json: @page.errors, status: :unprocessable_entity }
            end
        end
  end

    def page_params
        params.require(:page).permit(:title, :description, parts_attributes: [:id, :part_type, :part_title, :part_desc])
    end
end # End Pages Controller

路线

resources :projects do
    resources :pages
end

resources :pages

resources :parts

问题:

1) 表单未保存任何数据(无法编辑/更新当前页面或创建新页面)。 更新:已修复,请参阅下面我自己的答案。

2) 在部分我使用collection 有一个下拉菜单,但这些测试值现在是硬编码的。如何使用数据库中的列填充每个字段的下拉列表?

3) 来自部分的内联表单元素不会被渲染回主表单。我看到的只是“零件”标签,下面没有任何元素。 更新@pages.parts.build 解决了这个问题。

感谢你们能给我的任何帮助。

【问题讨论】:

  • 在您的控制器中尝试@page.parts.build 将新的零件实例添加到零件集合中。

标签: ruby-on-rails ruby twitter-bootstrap simple-form cocoon-gem


【解决方案1】:
  1. 您有一个 @page 对象,但没有 parts。因此,当它尝试渲染 fields_for 时,它确实如此!只是,零次。在您的控制器中添加@page.parts.build 以添加一个。

  2. 不确定;现在太累了。尝试将save 更改为save! 并将update_attributes 更改为update!,这样Rails 就会抛出错误而不是静默失败。顺便说一句,为什么你的page_params 里面有if params[:page]?那是不需要的;这就是require(:page) 所做的。

  3. ActiveRecord 提供了一个column_names 方法,它返回一个列名数组。

【讨论】:

  • 感谢您对 Ryan 的评论并对迟到的回复表示歉意。我必须阅读build 方法才能完全理解它的作用背后的细节,但这确实解决了我的那部分问题,所以谢谢。表单仍然没有保存 - 我现在正在使用 save!update! 但没有记录任何错误;事实上,更新记录时,我在终端上看到了完全相同的输出。有什么想法可以做吗?
【解决方案2】:

实际上,@page.parts.build 将始终构建一个新的part,即使用户没有请求此操作(这可能是您想要的)。现在您只为每个嵌套零件显示Add 按钮。我假设您只需要一个 Add 按钮,如下所示:

  .form-inline
    = f.simple_fields_for :parts do |part|
      = render 'parts_fields', f: part
      = link_to_add_association 'Remove Part', f, :parts            
    = link_to_add_association 'Add Part', f, :parts

这将始终显示Add Part 链接(并且仅显示一次)。

至于不保存,可能的原因有:

  • 数据未发布到服务器(检查您的日志文件,可能的原因是您的 html 中的错误,例如多个相同的 id)
  • 数据被强参数命令阻止
  • 数据被accepts_nested_attributes_forreject_if条件阻塞
  • 验证失败

现在,如果显示的代码是您的实际代码,一切似乎都正常。那么你能告诉我们发布到服务器的内容吗? (检查您的日志文件)。

【讨论】:

  • Nathan 感谢您抽出宝贵时间与我们联系!我实际上只是想通了为什么表单没有保存(我会发一篇关于它的帖子)。我在 OP 中更新了表单 + 部分;这个想法是让用户在整个表单中只有一个添加部分,并且每个添加的部分旁边都有一个删除部分。这是一张图片。问题:正如您所说,默认情况下始终构建一个部分,我该如何更改它,以便用户必须添加第一个?
【解决方案3】:

表单现在按预期保存数据。在我的一个部分中,我有两个相同的字段,因此为我造成了无声的冲突。此外,在我解决了这个问题后,我开始收到Unpermitted parameter: _destroy 错误,解决方法是将:_destroy 添加到parts_attributes 的必需参数列表中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多