【问题标题】:Rails 3 rendering form with an array of nested attributes after failing validation验证失败后,Rails 3 呈现带有嵌套属性数组的表单
【发布时间】: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


【解决方案1】:

我正在回答我自己的问题,因为我已经解决了问题。

由于“问题”模型中的拒绝_if,从“问题”中删除了空白“选项”。执行以下代码时应用了reject_if 语句,因此删除了空白“选项”。

@question = current_user.questions.build(params[:question])

我用 after_save 回调替换了reject_if,它删除了留空的选项。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    • 2014-09-20
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多