在适当的休息路线之外使用accepts_nested_attributes_for

时间:2016-01-08 02:25:58

标签: ruby-on-rails ruby ruby-on-rails-4

我正在为名为Project的模型构建设置向导。该模型具有许多相关信息,其中包括许多嵌套模型。

经过一些研究和相当多的试验和错误,我决定在SetupController中管理设置过程,使用:id参数来跟踪我所处的步骤,结果在这样的路径模式中:projects/:project_id/setup/:id/edit(基于this blog

以下是相关位:

项目模型

class Project < ActiveRecord::Base
  has_many :ratings
  accepts_nested_attributes_for :ratings, allow_destroy: true, reject_if: -> x { x[:value].blank? }
end

评级模型

class Rating < ActiveRecord::Base
  # has a null: false constraint on value
  belongs_to :project
end

设置控制器

ProjectSetupController < ApplicationController
  STEPS = %w(step_1 step_2 step_3)

  layout 'setups'

  def edit
    @project.ratings.build
    render step
  end

  def update
    if @project.update_attributes(project_params)
      if next_step && params[:button].downcase.include?('continue')
        redirect_to edit_project_setup_path(@project, next_step), flash: {success: "Updated project"}
      else
        redirect_to project_path(@project)
      end
    else
      flash.now[:error] = "Please complete all required fields"
      render step
    end
  end

  private

  def step
    STEPS.find {|s| s == params[:id].to_s.downcase}
  end

  def current_step_index
    STEPS.index(step)
  end

  def next_step
    STEPS[current_step_index+1]
  end

  def project_params
    params.require(:project).permit(:name, ratings_attributes: [:id, :value, :_destroy])
  end
end

除了涉及嵌套属性之外,这一切都很好。项目accepts_nested_attributes_for Ratings,但拒绝任何带有空值的评级。我希望用户能够提交包含空白值的表单,因为可以将多个评级字段动态添加到项目表单中,并且始终会有一个空的new字段,我只是不想要任何记录没有要保存的值。但是,当使用:id参数作为父模型的id之外的其他内容时,某些内容会变得混乱,并且在提交表单时不会丢弃这些记录。相反,他们点击评级数据库验证是否存在值,并抛出错误。

表格

 = simple_form_for @project, url: project_setup_path(@project, params[:id]), as: :project, html: {id: 'customization-form'} do |f|

  - @project.ratings.each do |rating|
    .rating-wrapper{class: rating.new_record? && "new"}

      = f.fields_for :ratings, rating do |ff|     
        = ff.input_field :value, placeholder: "Enter New Rating"

   = button_tag(type: 'submit') do
     Update

如果我使用params [:id]模拟提交作为我提交表单的项目的ID,那么一切都按预期工作(当然这会导致重定向错误,因为项目ID是不是一个有效的步骤),所以我觉得必须有一些方法将属性指向正确的id,唉,这个魔法超出了我。

目前可能的解决方法:

  • 我可以使用a将表单提交给常规项目控制器操作 按钮参数,将用户重定向回设置 过程

  • 我可以通过javascript从DOM中删除空值字段 提交

  • 如果我删除评级验证,我可以将表单提交为 是,并且所有空白评级都将被保存,但我可以删除它们 回调

目前我正在采用第一种解决方法,但是是否有更多的Rails-y解决方案允许我将此过程保留在设置控制器中,而无需删除数据库验证或使用javascript? blog article我在建议用于处理临时验证的子模型之后对我的向导进行了建模 - 我不认为这正是我在这里寻找的,但也许在那里&#39; sa我可以利用这样的方式吗?

0 个答案:

没有答案