gpt4 book ai didi

ruby-on-rails - Ruby : If column exists use it, 如果不添加到其他列

转载 作者:行者123 更新时间:2023-12-04 06:13:21 24 4
gpt4 key购买 nike

我正在解析 CSV 并尝试区分 Model 中的列和将添加到 JSONB :data 列的“虚拟”列。到目前为止,我得到了这个:

rows = SmarterCSV.process(csv.path)
rows.each do |row|
row.select! { |x| Model.attribute_method?(x) } # this ignores non-matches
Model.create(row)
end

从 CSV 行中删除Model 不匹配的列。相反,我想将所有这些数据添加到 Model 中名为 :data 的列中。我该怎么做?

编辑

select! 之前可能是这样的吗?

row[:data] = row.select { |x| !Model.attribute_method?(x) }

最佳答案

有多种方法可以做到这一点。一种特别直接的方法是使用 Hash#slice!来自 Rails 的 ActiveSupport 扩展,它的工作方式类似于 Array#slice! 并返回一个散列,其中包含那些未在其参数中给出的键,同时保留给定的键:

rows = SmarterCSV.process(csv.path)
attrs = Model.attribute_names.map(&:to_sym)

rows.each do |row|
row[:data] = row.slice!(*attrs)
Model.create(row)
end

附言这可能会在“愚蠢的 Ruby 技巧”下归档,但如果您使用的是 Ruby 2.0+,则可以利用双标 (**) 来实现这种紧凑的结构:

rows.each do |row|
Model.create(data: row.slice!(*attrs), **row)
end

附言如果您的 CSV 很大并且您发现自己有性能问题(调用 create 几千次 - 以及随后的数据库 INSERTs - 并不便宜),我建议检查出activerecord-import gem .它正是为这类事情而设计的。有了它你会做这样的事情:

rows = SmarterCSV.process(csv.path)
attrs = Model.attribute_names.map(&:to_sym)

models = rows.map do |row|
row[:data] = row.slice!(*attrs)
Model.new(row)
end

Model.import(models)

activerecord-import 文档中还有其他更快的选项。

关于ruby-on-rails - Ruby : If column exists use it, 如果不添加到其他列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32367502/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com