Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Ruby:如果列存在,则使用它,如果不存在,则添加到其他列_Ruby On Rails_Csv_Ruby On Rails 4_Jsonb_Smartercsv - Fatal编程技术网

Ruby on rails Ruby:如果列存在,则使用它,如果不存在,则添加到其他列

Ruby on rails Ruby:如果列存在,则使用它,如果不存在,则添加到其他列,ruby-on-rails,csv,ruby-on-rails-4,jsonb,smartercsv,Ruby On Rails,Csv,Ruby On Rails 4,Jsonb,Smartercsv,我正在解析CSV并试图区分模型中的列和将添加到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行中删除与模型不匹配的列。相反,我想将所有这些数据添加到模型中名为:dat

我正在解析CSV并试图区分模型中的列和将添加到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行中删除与模型不匹配的列。相反,我想将所有这些数据添加到模型中名为:data的列中。我该怎么做

编辑

像这样的选择之前!也许吧

您是否尝试过:

row[:data] = row.delete_if {|k,v| !Model.attribute_method?(k) }
Model.create(row)
这将从行哈希中删除元素,并将键值对添加回:data key下的行。

您可以尝试使用此has\u属性吗


有很多方法可以做到这一点。一个特别简单的方法是使用Rails的ActiveSupport扩展,它的工作原理类似于Arrayslice!并返回一个散列,其中包含参数中未给定的键,同时保留给定的键:

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+你可以利用双splat**来实现这个紧凑的结构:

rows.each do |row|
  Model.create(data: row.slice!(*attrs), **row)
end
p.p.S.如果您的CSV很大,并且您发现自己在调用create数千次后出现性能问题,并且后续的数据库插入并不便宜,那么我建议您检查一下。它正是为这类事情而设计的。使用它,您可以执行以下操作:

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导入文档中还有其他更快的选项。

我喜欢keep\u if,但有\u属性?对我不起作用。rails 3.2+它会起作用的,或者那是一个dope one liner!谢谢很乐意帮忙!我添加了一个关于宝石的注释,你可能会发现它很有用;看一看,不是你第一次参加牛仔竞技表演吧?非常感谢。
rows.each do |row|
  Model.create(data: row.slice!(*attrs), **row)
end
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)