即使字段不为空,验证字段的存在也会失败

Nat*_*han 1 validation activerecord ruby-on-rails

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

"record"=>{... "type_array"=>["accounting"], ...}
Run Code Online (Sandbox Code Playgroud)

它与创建新记录时的参数看起来相同.在该领域New.html.erb,并Edit.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>
Run Code Online (Sandbox Code Playgroud)

Record.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
Run Code Online (Sandbox Code Playgroud)

我错过了什么吗?当我删除type_array验证并填写表单时,它的行为类似于type_array为空.沿着这条线的某个地方,它必定是丢失的东西.

我感谢任何帮助.

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

Luk*_*uke 5

删除该行attr_accessor :type_array.

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

你几乎从不使用attr_accessor它或它的兄弟姐妹attr_readerattr_writerRails,因为你想要处理模型属性,而不是实例变量.

编辑:您正在使用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
Run Code Online (Sandbox Code Playgroud)

由于您需要最后一个函数定义,请参阅此问题.