在Rails中将嵌套模型的验证错误作为json返回的更好方法是什么?

时间:2016-03-31 06:15:39

标签: ruby-on-rails json ruby-on-rails-4 rubygems

我有班级订单,可以内容条目。每个条目都可以是复杂类型,并且由其他条目组成。

class Order < ActiveRecord::Base
  accepts_nested_attributes_for :entries
end

class Entry < ActiveRecord::Base
  accepts_nested_attributes_for :members, allow_destroy: true
end

在表单中,我使用fields_for

在表单中生成了rails
<input autocomplete="off" class="string required form-control" id="order_entries_attributes_1459329286687_members_attributes_1459329286739_title" name="order[entries_attributes][1459329286687][members_attributes][1459329286739][title]" placeholder="Наименование" type="text">

所以,我提交了一份订单,例如有2个条目,5个成员有一些验证错误(2个成员没有标题)并且它传递给控制器​​

class OrdersController
  def update
    if @order.update(order_params)
      render json: @order
    else
      render json: @order.errors, status: :unprocessable_entity
    end
  end
end

它给我这个

{"entries.members.title":["cant be blank"]}

问题是我无法找到哪个条目及其中的哪个成员有验证错误,这就是为什么我无法突出显示此字段的原因。此外,它合并了类似的错误。这是问题。

在提交时,我传递唯一索引(在名称属性中),并且rails正确地使用它来创建嵌套模型,如果错误响应包含此索引,那将是很好的。

有没有其他方法可以从服务器返回漂亮的索引错误,并使用rails作为json而不用痛苦?

1 个答案:

答案 0 :(得分:1)

更新为与Rails嵌套参数

具有相同的格式
render json: {
  order: {
    entries: @order.entries.enum_for(:each_with_index).collect{|entry, index|
      {
        index => {
          id: entry.id,
          errors: entry.errors.to_hash,
          members: entry.members.enum_for(:each_with_index).collect{|member, index|
            { 
              index => {
                id: member.id,
                errors: member.errors.to_hash
              }
            } unless member.valid?
          }.compact
        }
      } unless entry.valid?
    }.compact
  }
}

你应该得到一个JSON响应,如:

{
  order: {
    entries: [
      0: {
        id: 1, # nil, if new record
        errors: {},
        members: [
          0: {
            id: 7, # nil, if new record
            errors: {
              title: ["cant be blank"]
            }
          },
          1: {
            id: 13, # nil, if new record
            errors: {
              title: ["cant be blank"]
            }
          }
        ]
      }
    ]
  }
}

P.S。也许其他人知道这样做的轨道集成方式。否则,我会说这可能是git中Rails的一个很好的功能请求。