我正在为名为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我可以利用这样的方式吗?