替换转置方法?

时间:2014-03-31 21:16:28

标签: ruby-on-rails ruby arrays prawn transpose

我有以下代码:

table([
          ["UnitID", "First Name", "NPS Score", "Comments"],
          *[invite_unitid_arr, invite_name_arr, nps_score_integers_final, comment_arr]
          .transpose.reject{ |x| x[3].empty? }
      ], :position => :center, :column_widths => {0 => 50, 1 => 60, 2 => 60, 3 => 40, 4 => 150}) do
  row(0).style :background_color => 'C0C0C0'
end

我在数组数组上调用transpose。我正在重构这个代码,现在我有一个模型对象数组:

array = Model.all

如何重写上述内容,说“循环遍历每个模型(Model1,Model2等)并使用属性unit_id,first_name,nps_score创建一行,注释如下:Model1[:unit_id],Model1[:first_name],Model1[:nps_score],Model1[:comment]

2 个答案:

答案 0 :(得分:0)

我不完全确定你想在这里实现什么,但似乎你正在寻找pluck方法。由于rails 4允许您一次拔出多列(默认情况下会拔除所有列)。所以看来:

Model.pluck(:unit_id, :first_name, :nps_score, :comment)

您正在寻找什么 - 并且实际上要好得多,因为它没有实例化新对象并只对db进行一次调用。 。它将返回2d数组,每个模型一行。如果您更喜欢使用相同列的不同值,请在上面添加转置。

答案 1 :(得分:0)

如果我理解正确,你就有这样一个对象数组:

my_models = [ <MyModel id: 1, unit_id: 123, first_name: "Xxx", nps_score: 100, ...>,
              <MyModel id: 2, unit_id: 456, first_name: "Yyy", nps_score: 200, ...>,
              ...
            ]

你想要一个像这样的数组:

[ [ "UnitID", "First Name", "NPS Score", "Comments" ],
  [ 123,      "Xxx",        100,         "..."      ],
  [ 456,      "Yyy",        200,         "..."      ],
  ...
]

你真正需要做的就是:

headers = [ "UnitID", "First Name", "NPS Score", "Comments" ]

data = my_models.map do |model|
  [ model.unit_id, model.first_name, model.nps_score, model.comments ]
end

rows = [ headers, *data ]

或者...

data = my_models.map do |model|
         model.attributes.values_at(:unit_id, :first_name, :nps_score, :comments)
       end

(无论哪种方式,你都可以将其作为一个单行,但请注意你的代码的可读性。)

当然,最好只选择您要使用的列,这样您就可以执行此操作(添加whereorder等所有内容你需要):

my_models = MyModel.select([ :unit_id, :first_name, :nps_score, :comments ]).where(...)
data = my_models.map(&:attributes)
# => [ [ 123, "Xxx", 100, "..." ],
#      [ 456, "Yyy", 200, "..." ],
#      ...
#    ]

在Rails 4中,pluck方法需要多个参数,这使得这更容易:

data = MyModel.where(...).pluck(:unit_id, :first_name, :nps_score, :comments)
# => [ [ 123, "Xxx", 100, "..." ],
#      [ 456, "Yyy", 200, "..." ],
#      ...
#    ]