【问题标题】:Create CSV over the hash array loop在哈希数组循环上创建 CSV
【发布时间】:2020-09-01 01:08:37
【问题描述】:

在我的 Rails6 应用程序中,我想使用导出到 CSV 文件的日志创建管理记录器活动 - 为此,我使用 paper_trail gem 记录所有管理活动。我想存储所有已经产生的差异,这就是为什么我使用来自 paper_trail gem 的changeset 方法,它给了我以下结果:

[33] pry(main)> PaperTrail::Version.last.changeset
=> {"name"=>["", "no name"], "is_initial_survey_filled"=>[false, true], "updated_at"=>[Mon, 31 Aug 2020 20:31:45 UTC +00:00, Mon, 31 Aug 2020 23:43:17 UTC +00:00]}

每个键的第一个值代表旧数据,数组中的第二个值代表新数据,如下所示:

name[0] = "" #old data
name[1] = "no name" #new data

is_initial_survey_filled[0] = false #old data
is_initial_survey_filled[1] = true #new data

如何获取数据并将所有这些操作放入 CSV 文件中?

我正在尝试这样的事情:

LOG_HEADERS = ['Created at', 'Acting User', 'Old Data', 'New Data'].freeze

def call
  FileUtils.mkdir_p(base_path)

  CSV.open(file_path, 'w', col_sep: ';', write_headers: true, headers: LOG_HEADERS, encoding: 'UTF-8') do |csv|
    PaperTrail::Version.all.each do |version|
      old_data_value = version.changeset.present? ? version.changeset.each { |_k, v| v[0] } : ''
      new_data_value = version.changeset.present? ? version.changeset.each { |_k, v| v[1] } : ''
      csv << [version.created_at,
              version.whodunnit,
              old_data_value,
              new_data_value]
    end
  end
end

但我在两列中得到相同的数据,而不是漂亮的日志:

在 old_data 列中:

{"name"=>["", "no name"], "is_initial_survey_filled"=>[false, true], "updated_at"=>[Mon, 31 Aug 2020 20:31:45 UTC +00:00, Mon, 31 Aug 2020 23:43:17 UTC +00:00]}

在新数据列中

{"name"=>["", "no name"], "is_initial_survey_filled"=>[false, true], "updated_at"=>[Mon, 31 Aug 2020 20:31:45 UTC +00:00, Mon, 31 Aug 2020 23:43:17 UTC +00:00]}

[编辑]

所需的 CSV 应该是这样的:

【问题讨论】:

  • 您能否在问题中添加所需 CSV 输出的示例?目前还不是 100% 清楚您希望如何将集合(旧值和新值实际上都是集合,对)打包到单个 CSV 列中。
  • @KonstantinStrukov 问题已更新。

标签: ruby-on-rails ruby csv


【解决方案1】:

只需使用map 方法而不是eacheach 总是返回调用它的集合。 map 将从传递给它的块返回数据。将 version.changeset.each { |_k, v| v[0] } : '' 更改为 version.changeset.map { |_k, v| v[0] } : '' 即可。

编辑:刚刚意识到您需要哈希而不是数组。 version.changeset.map { |k, v| [k, v[0]] }.to_h : '' 将完成这项工作。

【讨论】:

  • 它可以使用map 完成这项工作,但不能使用.to_h,这给了我一个错误:TypeError: wrong element type String at 0 (expected array)。除了想要的输出(在我的问题的底部)之外,我在一个旧数据列中得到了类似 ["name: ", "is_initial_survey_filled: false"] 的东西,而不是像我描述的那样的两列。
  • 您也需要更改块内的代码(我猜您错过了那部分)。您还需要在 new_data_value 中应用相同的更改。
猜你喜欢
  • 2018-12-21
  • 2015-08-22
  • 1970-01-01
  • 1970-01-01
  • 2017-04-12
  • 1970-01-01
  • 1970-01-01
  • 2022-11-12
  • 1970-01-01
相关资源
最近更新 更多