【问题标题】:Validating field's presence fails even though the field is not blank即使字段不为空,验证字段是否存在也会失败
【发布时间】:2011-08-05 15:36:57
【问题描述】:

我正在尝试使用复选框中的值填充数组。创建记录时它工作得很好,但在编辑时验证失败。参数看起来正确,这让我很困惑:

"record"=>{... "type_array"=>["accounting"], ...}

它看起来与创建新记录的参数相同。 New.html.erbEdit.html.erb 中的字段也使用相同的标记。

Edit.html.erb

<div class="field">
  <%= f.label :type_array, "What type of record?" %><br />
  <% ["accounting", "agriculture", "automotive"].each do |type| %>
    <%= check_box_tag 'record[type_array][]', type, (true if @record.type_list.include? type),
                      :id => type %>
    <%= label_tag type, type.titleize, :class => type %><br />
  <% end %>
</div>

记录部分.rb

validates :type_array, :presence => true
attr_accessor :type_array
attr_accessible :type_array
before_validation :set_type_list

private

def set_type_list
  self.type_list = type_array.join ',' if type_array.present?
end

我错过了什么吗?当我删除 type_array 验证并填写表单时,它的行为就像 type_array 为空一样。沿着这条线的某个地方,它一定是丢失了或什么的。

感谢您的帮助。

(旁注:如果有人有更好的方法来制作复选框列表,请告诉我)

【问题讨论】:

    标签: ruby-on-rails validation activerecord


    【解决方案1】:

    删除attr_accessor :type_array这一行。

    这将为新实例变量创建访问器方法,而不是模型属性type_array,这意味着@record.type_array 现在引用该实例变量而不是属性。

    您几乎从不在 Rails 中使用attr_accessor 或它的兄弟attr_readerattr_writer,因为您想处理模型属性,而不是实例变量。

    编辑:您使用type_array 作为虚拟属性。

    class Record < ActiveRecord::Base
      validates :type_array, :presence => true
      attr_accessible :type_array
    
      def type_array=(val)
        self.type_list = val.join ','
      end
    
      def type_array
        self.type_list.split ','
      end
    
      def type_array_before_type_cast
        type_array
      end
    end
    

    关于您需要最后一个函数定义的原因,请参阅this question

    【讨论】:

    • 我在记录表中没有 type_array 列,所以我不需要包含 attr_accessor 来“创建”它吗?基本上,我使用复选框来填充数组 (type_array),然后在模型中处理它并将其保存为 type_list。当我删除 attr_accessor 时,它会引发 undefined local variable or method type_array'` 异常。 (我用 type_list 部分编辑了模型代码。)
    • 啊,您将它用作虚拟属性。我会相应地编辑我的答案。
    • 酷,我从来没有想过要这样拆分它。但是,在编辑记录时它仍然不起作用。它不会引发任何验证错误,所以很好。创建新记录时它仍然有效,所以这也很好。参数看起来仍然正确 ("type_array"=&gt;["construction", "healthcare", "nonprofits"])。让我困惑不已的是参数看起来很好,以及创建新记录如何完美地工作。感谢您迄今为止的帮助。
    • 没什么。它保存记录而不引发任何内容,但 type_list 不会更改。我又检查了几个复选框,保存了记录,但 type_list 假装什么也没发生。如果重要的话,我这样做是为了使用acts_as_taggable_one 设置标签。同样的方法适用于另一个模型,这很奇怪。
    • 尝试从控制台更新记录,看看是否可行。这是执行虚拟属性的标准方法,而创建记录工作正常这一事实表明问题出在编辑操作的其他地方。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    • 2014-05-15
    • 1970-01-01
    • 2019-10-18
    • 1970-01-01
    • 2017-12-24
    相关资源
    最近更新 更多