大虾错误"数据必须是可细胞对象的二维数组"

Azr*_*ren 3 ruby-on-rails prawn

我正在使用Prawn生成PDF文档,但在尝试生成项目表时遇到上述错误.关于如何解决这个问题的任何想法?

应用程序/模型/ storage_request.rb

class StorageRequest < ActiveRecord::Base
  has_many :packages

  accepts_nested_attributes_for :packages, :allow_destroy => true
  attr_accessible :user_id, :state, :packages_attributes
end
Run Code Online (Sandbox Code Playgroud)

应用程序/模型/ package.rb

class Package < ActiveRecord::Base
  belongs_to :storage_request
  has_many :items

  accepts_nested_attributes_for :items, allow_destroy: true
  attr_accessible :user_id, :state, :items_attributes
end
Run Code Online (Sandbox Code Playgroud)

应用程序/模型/ item.rb的

class Item < ActiveRecord::Base
  belongs_to :package

  attr_accessible :name, :user_id
end
Run Code Online (Sandbox Code Playgroud)

应用程序/ PDF文件/ storage_request_pdf.rb

class StorageRequestPdf < Prawn::Document
  def initialize(storage_request, view)
    super(top_margin: 50)
    @storage_request = storage_request
    @view = view
    list_items
  end

  def list_items
    move_down 20
    text "Summary", size: 30, style: :bold, align: :center

    table item_rows do
      row(0).font_style = :bold
      self.row_colors = ["DDDDDD", "FFFFFF"]
      self.header = true
    end
  end

  def item_rows
    @storage_request.packages.map do |package|
      package.items.map do |item|
        ([["ID", "Item Name"]] +
        [item.id, item.name])
      end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

Ste*_*fan 10

您的item_rows方法返回格式错误的数组.它将标头添加到每一行并返回一个如下数组:

[ [["ID", "Item Name"], 1, "Foo"],
  [["ID", "Item Name"], 2, "Bar"],
  [["ID", "Item Name"], 3, "Baz"] ]
Run Code Online (Sandbox Code Playgroud)

而Prawn期待这样的数组:

[ ["ID", "Item Name"],
  [1, "Foo"],
  [2, "Bar"],
  [3, "Baz"] ]
Run Code Online (Sandbox Code Playgroud)

您应该始终为代码编写测试,以便尽早发现此类错误.

我将在单独的方法中定义行和标头:

def item_header
  ["ID", "Item Name"]
end

def item_rows
  @storage_request.packages.map do |package|
    package.items.map { |item| [item.id, item.name] }
  end
end

def item_table_data
  [item_header, *item_rows] 
end
Run Code Online (Sandbox Code Playgroud)

并创建表:

table(item_table_data) do
  # ...
end
Run Code Online (Sandbox Code Playgroud)

item_rows方法仍然有点难看,因为它深入到对象中.我会添加一个has_many:通过关联StorageRequest:

class StorageRequest < ActiveRecord::Base
  has_many :packages
  has_many :items, :through => :packages
Run Code Online (Sandbox Code Playgroud)

并重构item_rows方法:

def item_rows
  @storage_request.items { |item| [item.id, item.name] }
end
Run Code Online (Sandbox Code Playgroud)