0

我是新来的Ruby和Rails,我试图把一个嵌套窗体,最终创建一个页面,但也允许用户创建个别部分内嵌提交之前这一页。内联表单包含两个按钮,一个添加一个部分,另一个删除它。以下是我的相关文件(请让我知道如果你需要看到任何其他的),我会列出我以后有问题:嵌套窗体不呈现或保存数据

仅供参考,我使用的宝石:SlimSimple Formcocoon和Bootstrap。 On 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 

/模型/一部分。 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解决了这个问题。

欣赏你们可以给我的任何帮助。

+1

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

回答

0

表单现在正在按预期保存数据。在我的一个部分中,我有两个相同的领域,从而为我创造了一个无声的冲突。另外,在我解决这个问题之后,我开始得到一个Unpermitted parameter: _destroy错误,并且修复方法是将:_destroy添加到parts_attributes所需的参数列表中。

1
  1. 你有没有parts一个@page对象。所以当它试图渲染fields_for时,它确实!只是,零次。在您的控制器中添加@page.parts.build以添加一个。

  2. 不确定;现在太累了。尝试更改savesave!update_attributesupdate!,以便Rails引发错误而不是以失败方式失败。顺便说一句,为什么你的page_params里面有if params[:page]?这是不需要的;这就是require(:page)所做的。

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

+0

感谢您对Ryan发表评论,并对迟到的反应表示歉意。我必须阅读'build'方法来完全理解它背后的细节,但这确实解决了我的问题的一部分,所以谢谢。表单仍然没有保存 - 我现在使用'save!'和'update!',但没有记录错误;事实上,当更新记录时,我在终端上看到相同的确切输出。任何想法可以做到这一点? – Blueshift

1

其实,@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,如错误多个相同IDS)
  • 数据通过您的强参数命令
  • 的数据由reject_if条件的accepts_nested_attributes_for
  • 失败的验证闭锁闭锁

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

+0

弥敦道感谢您抽空接触!我实际上只是想出了为什么表格没有保存(我会发表一篇文章)。我更新了OP中的表格+部分;这个想法是让用户在整个表单中只有一个添加部分,并且每个部分旁边都有一个删除部分。这是一张图片。问题:如你所说,一个零件总是默认生成,我怎么改变这个,所以用户必须添加第一个零件? – Blueshift