rails中的数组字段消除了编辑

时间:2015-06-20 21:41:30

标签: ruby-on-rails ruby postgresql

编辑作为二维数组的表单字段时,如果编辑导致任何两个元素相等,则删除第二个相似元素。如果我在阵列上调用了uniq。我正在寻找关于为什么会发生这种情况的线索以及任何阻止它发生的想法。

<的修改>我应该包含从Postgres返回的错误... PG :: InvalidTextRepresentation - 错误:多维数组必须具有匹配维度的数组表达式

背景: 我正在使用Rails 4.2.0,Ruby 2.1.1p76和Postgres 9.3.5。我有一个Invoice模型,它通过CompileInvoice保存来自其他模型的数据,CompileInvoice是一个单项服务,在项目完成时运行,并且所有相应的人工和材料数据都已更新。 Invoice模型的目的是将来自多个模型的数据合并到一个记录中,并允许它以半不可变的形式存储。我说半不可变,因为我的客户的会计部门想要一个机会查看发票并在发送给客户之前进行更正。我的问题与此编辑有关。

有问题的字段是“材料”,它的创建方式如下:

add_column :invoices, :materials, :text, array: true, default: []

在我的发票模型中,我使用以下getter和setter来保留数组的二维配置:

class Invoice < ActiveRecord::Base
(...)
    def materials_list= input
    list =[]

    input.each do |key, value|
      list << value
    end

    self.materials = list.each_slice(4).to_a
  end

  def materials_list
    self.materials
  end
end

InvoicesController中的invoice_params方法如下所示:

class InvoicesController < ApplicationController
(...)
  private
    def invoice_params
      params.require(:invoice).permit(
        (...)
        :materials_total
        ).tap do |whitelisted|
          whitelisted[:materials_list] = params[:invoice][:materials_list]
        end
    end
end

我知道通常我会想使用:materials_list => []声明material_list是一个数组,但是当我这样做时(作为我列入白名单的块的一部分或在允许的参数范围内)对数据的任何更改不要通过模型。

这是来自edit.html.erb的相关html:

thead>
  <tr>
    <th>Description</th>
    <th>Quantity</th>
    <th>Unit Price</th>
    <th>Extended Price</th>
  </tr>
</thead>
<tbody>
  <%= f.fields_for :materials_list do |mm| %>
    <% @invoice.materials_list.try(:each) do |element| %>
      <tr>
        <% element.try(:each) do |cell| %>
          <td>
            <%= mm.text_field cell, :value => cell, :class => 'form-control' %>
          </td>
        <% end %>
      </tr>
    <% end %>
  <% end %>
</tbody>

这是一个请求参数,现在有十一个元素而不是构成阵列中三个四元素数组的十二个元素 - 将数量从“1”中删除为2到1,这使得第三个和第四个元素成为第一个数组相等。

"materials_list"=>{"one"=>"one", "1"=>"1", "3.01"=>"3.01", "two"=>"two",
"3"=>"3", "4.01"=>"4.01", "12.03"=>"12.03", "three"=>"three", "4"=>"4",
"5.01"=>"5.01", "20.04"=>"20.04"},

这是IRB中的数组:

materials:
  [["one", "2", "3.01", "6.02"],
  ["two", "3", "4.01", "12.03"],
  ["three", "4", "5.01", "20.04"]]

我可以整天编辑这个数组,只有当我使两个元素相等时它才会中断。如上所述,就像在阵列上调用uniq一样。

1 个答案:

答案 0 :(得分:0)

我最终找到了解决问题的方法,虽然我对其他想法持开放态度,因为我不确定它是否真的是最好的解决方案。在我的评论中,我注意到post params返回了一系列哈希值。我最后设置了带有数组索引的哈希的键,以避免重复,并依赖Invoice模型中的materials_list方法在保存之前将哈希值转换为数组。

我还需要放弃在视图中使用表格,因为我不再拥有要在视图中迭代的数组数组。

edit.html.erb

<div class="row" id="miscMaterialsTable">
  <% @invoice.misc_materials_list.try(:each_with_index) do |cell, i| %>
    <%= f.fields_for :misc_materials_list do |array_form| %>
      <div class="col-sm-3">
        <%= array_form.text_field [i], :value => cell, class: 'form-control' %>
      </div>
    <% end %>
  <% end %>
</div>

invoice.rb

def misc_materials_list= input
  list =[]

  input.each do |key, value|
    list << value
  end

  self.misc_materials = list.each_slice(4).to_a
end

def misc_materials_list
  self.misc_materials.flatten
end