【发布时间】:2011-07-11 21:37:33
【问题描述】:
我的问题模型有很多选项。
在我的问题控制器新操作中,我为我的用户创建了五个选项
def new
@question = Question.new
5.times.with_index do |index|
@question.options.build(:order => index)
end
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @question }
end
end
在视图中,我遍历所有选项
- form_for(@question) do |f|
.field
= f.label :title, t("question.title")
= show_errors_for(@question, :title)
= f.text_field :title
- @question.options.each do |option|
- f.fields_for :options, option do |o|
.field
= o.label :option, t("question.option_no", { :index => option.order })
= o.text_field :option
= o.hidden_field :order, :value => option.order
.actions
= f.submit t("add_question.create")
我的问题模型如下所示
class Question < ActiveRecord::Base
attr_accessible :title, :options_attributes
belongs_to :user
has_many :options
accepts_nested_attributes_for :options, :reject_if => proc { |attributes| attributes['option'].blank? }
validates :title, :length => { :maximum => 100 }, :presence => true
validate :min_no_of_options
def min_no_of_options
if self.options.size < 3
errors.add_to_base "Must have at least three options"
end
end
end
我的问题控制器创建操作
def create
if current_user
@question = current_user.questions.build(params[:question])
else
@question = Question.new(params[:question])
end
if @question.save
redirect_to(@question, :success => t('question.flash_success'))
else
flash.now[:error] = t("question.flash_error")
render :action => "new"
end
end
现在,当我在表单中只输入两个选项并点击创建按钮时,验证会阻止模型被保存。哪个好。但是当创建动作再次呈现新动作时,只显示我填写的选项字段。留空的三个选项字段消失了。
如果我将创建操作中的“@question.save”替换为“false”,则行为相同。因此,这表明我在 create 操作中创建 @question 变量的方式导致我的空选项被丢弃。
但是,如果我改为从我的问题模型中删除 :reject_if ,则会在按预期保存失败的问题后显示空选项。 (我在我的选项模型中对选项属性进行了存在验证)所以这告诉我,我在创建操作中创建 @question 变量的方式没有任何问题。它不会丢弃空的选项。那么他们被踢到哪里去了呢?
有一个非常相似的问题,但其中的答案不是我想做的事情。虽然这可能是我必须做的事情。 rails fields_for does not render after validation error on nested form
编辑
在使用 rails 控制台进行了更多研究后,我注意到它确实是 @question 变量的创建,其中空选项被丢弃。发生这种情况是因为我在问题模型中定义了reject_if。在从模型中注释掉 reject_if 之后,空选项被添加到 @question 变量中。
所以我想我需要删除 reject_if 并使用 after_save 回调来销毁数据库中的空选项。这样,在保存问题之前,我将有空选项与问题一起出现。
【问题讨论】:
-
我需要补充一点,使用单词“order”作为属性名称不是一个好主意。它给我带来了一些其他问题,在我将该属性重命名为“ordering”后这些问题就消失了。
标签: ruby-on-rails-3 nested-forms