【发布时间】:2017-05-03 11:09:00
【问题描述】:
我正在尝试将保存在 xls 中的数据上传到我的 rails db。我已经尝试了几个不同的教程来完成这项工作,并概述了我在下面每个问题上遇到的问题。我不介意我最终使用哪种方法,我只是想不出如何尝试使用这些方法中的任何一种来解决这个问题。
Importing CSV files by RichonRails
型号:
class Randd::Field < ApplicationRecord
require 'csv'
def self.import(file)
CSV.foreach(file.path, headers: true) do | row |
randd_field_hash = row.to_hash
randd_field = Randd::Field.where(id: randd_field_hash["id"])
if randd_field.count == 1
randd_field.first.update_attributes(randd_field_hash)
else
Randd::Fields.create!(randd_field_hash)
# else
# Randd::Field.create! row.to_hash
end
end
end
end
路线:
namespace :randd do
resources :fields do
collection {post :import }#do
# post :create
end
end
控制器:
class Randd::FieldsController < ApplicationController
def index
@randd_fields = Randd::Field.all
end
def new
@field = Randd::Field.new
end
def create
# @field = Randd::Field.new(randd_field_params)
Randd::Field.create(params[:randd_field][:file])
redirect_to action: "index", notice: "Data imported"
end
def show
redirect_to action: "index"
end
def import
Randd::Field.import(params[:file])
# Randd::Field.create(params[:randd_field]['file'])
redirect_to action: "index", notice: "Data imported"
end
private
def randd_field_params
params.fetch(:randd_field, {}).permit(:title, :anz_reference)
end
end
当我保存并尝试时,我收到一条错误消息:
undefined method `path' for nil:NilClass
错误信息指向模型中的导入方法
GoRails 教程:
我尝试按照 GoRails 教程从 csv 文件导入数据。
在我的 rails 应用程序中,我已将文件保存为 for_codes.csv。
在我的 lib/tasks 文件夹中,我创建了一个名为:import.rake 的文件
在我的 input.rake 文件中,我有:
require 'csv'
namespace :import do
desc "import research fields from csv"
task rannd_fields: :environment do
filename = File.join Rails.root, 'for_codes.csv'
counter = 0
CSV.foreach(filename, headers: true) do | row |
p row ["anz_reference"]
for_code = Randd::Field.create(anz_reference: row["anz_reference"], title: title)
counter += 1 if randd_field.persisted?
end
puts "Imported #{counter} field codes"
end
end
当我在控制台中尝试这个时,使用:
bundle exec rake import:randd_fields
我收到一条错误消息:
NameError: undefined local variable or method `randd_fields' for main:Object
我要记录的模型被称为:
class Randd::Field < ApplicationRecord
数据库中的表被调用:
randd_fields
谁能看到我需要做什么才能完成这项任务?
回溯
bundle exec rake import:rannd_fields
rake aborted!
ArgumentError: invalid byte sequence in UTF-8
/Users/live/lib/tasks/import.rake:9:in `block (2 levels) in <top (required)>'
/Users/.rvm/gems/ruby-2.3.1@global/gems/rake-11.3.0/exe/rake:27:in `<top (required)>'
/Users/.rvm/gems/ruby-2.3.1/bin/ruby_executable_hooks:15:in `eval'
/Users/.rvm/gems/ruby-2.3.1/bin/ruby_executable_hooks:15:in `<main>'
Tasks: TOP => import:rannd_fields
(See full trace by running task with --trace)
MacBook-Pro:live em$ bundle exec rake import:rannd_fields --trace
** Invoke import:rannd_fields (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute import:rannd_fields
rake aborted!
ArgumentError: invalid byte sequence in UTF-8
/Users/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/csv.rb:2016:in `=~'
/Users/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/csv.rb:2016:in `init_separators'
/Users/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/csv.rb:1538:in `initialize'
/Users/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/csv.rb:1273:in `new'
/Users/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/csv.rb:1273:in `open'
/Users/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/csv.rb:1130:in `foreach'
/Users/live/lib/tasks/import.rake:9:in `block (2 levels) in <top (required)>'
/Users/.rvm/gems/ruby-2.3.1@global/gems/rake-11.3.0/lib/rake/task.rb:248:in `block in execute'
/Users/.rvm/gems/ruby-2.3.1@global/gems/rake-11.3.0/lib/rake/task.rb:243:in `each'
/Users/.rvm/gems/ruby-2.3.1@global/gems/rake-11.3.0/lib/rake/task.rb:243:in `execute'
/Users/.rvm/gems/ruby-2.3.1@global/gems/rake-11.3.0/lib/rake/task.rb:187:in `block in invoke_with_call_chain'
/Users/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/monitor.rb:214:in `mon_synchronize'
/Users/.rvm/gems/ruby-2.3.1@global/gems/rake-11.3.0/lib/rake/task.rb:180:in `invoke_with_call_chain'
/Users/.rvm/gems/ruby-2.3.1@global/gems/rake-11.3.0/lib/rake/task.rb:173:in `invoke'
/Users/.rvm/gems/ruby-2.3.1@global/gems/rake-11.3.0/lib/rake/application.rb:152:in `invoke_task'
/Users/.rvm/gems/ruby-2.3.1@global/gems/rake-11.3.0/lib/rake/application.rb:108:in `block (2 levels) in top_level'
/Users/.rvm/gems/ruby-2.3.1@global/gems/rake-11.3.0/lib/rake/application.rb:108:in `each'
/Users/.rvm/gems/ruby-2.3.1@global/gems/rake-11.3.0/lib/rake/application.rb:108:in `block in top_level'
/Users/.rvm/gems/ruby-2.3.1@global/gems/rake-11.3.0/lib/rake/application.rb:117:in `run_with_threads'
/Users/.rvm/gems/ruby-2.3.1@global/gems/rake-11.3.0/lib/rake/application.rb:102:in `top_level'
/Users/.rvm/gems/ruby-2.3.1@global/gems/rake-11.3.0/lib/rake/application.rb:80:in `block in run'
/Users/.rvm/gems/ruby-2.3.1@global/gems/rake-11.3.0/lib/rake/application.rb:178:in `standard_exception_handling'
/Users/.rvm/gems/ruby-2.3.1@global/gems/rake-11.3.0/lib/rake/application.rb:77:in `run'
/Users/.rvm/gems/ruby-2.3.1@global/gems/rake-11.3.0/exe/rake:27:in `<top (required)>'
/Users/.rvm/gems/ruby-2.3.1@global/bin/rake:23:in `load'
/Users/.rvm/gems/ruby-2.3.1@global/bin/rake:23:in `<main>'
/Users/.rvm/gems/ruby-2.3.1/bin/ruby_executable_hooks:15:in `eval'
/Users/.rvm/gems/ruby-2.3.1/bin/ruby_executable_hooks:15:in `<main>'
Tasks: TOP => import:rannd_fields
下一次尝试
接下来我尝试在我的 rails 应用程序中创建一个全新的文件。我输入了这三行:
anz_reference |标题 010104p |组合数学和离散数学(不包括物理组合) 010107p |数理逻辑、集合论、格和通用代数
第一行是标题。它们匹配 Randd::Field 模型上的属性。
接下来的两行是我尝试导入的内容。单元格值由 | 分隔(如 GoRails 视频中所示)。
当我尝试这个时,我得到了与上面发布的相同的错误:
$ bundle exec rake import:randd_fields --trace ** 调用导入:randd_fields (first_time) ** 调用环境(first_time) ** 执行环境 ** 执行导入:randd_fields 零 耙中止! NameError: main:Object 的未定义局部变量或方法“标题”
谁能看出我做错了什么?
我也试过这个教程 How to import CSV files in Rails by Matt Morgante 并尝试使用 rails cast 和 Roo gem 来达到同样的目的。这些选项都不起作用 - Rails Cast 很旧,所以可能已经过时了,并且在另一个教程的帖子中的 cmets 显示许多其他人无法使用这种方法 - 也许 Rails 中的事情已经改变了被提议。
GoRails 论坛上建议该问题可能是由于 CSV 文件未编码为 UTF-8 规范。有人建议可以通过将数据传输到谷歌驱动器中的工作表然后将其下载为 csv 以与 rails 一起使用来克服这个问题。我试过这个。
当我使用在 xls 中创建的文件运行 rake 任务时,我遇到了同样的错误。
钟的建议
接受钟的建议,我尝试将 import.rake 任务更改为:
require 'csv'
namespace :import do
desc "import research fields from csv"
task randd_fields: :environment do
filename = File.join Rails.root, 'for_codes.csv'
counter = 0
CSV.foreach(filename, headers: true) do | row |
p row ["anz_reference"]
# for_code = Randd::Field.create(anz_reference: row["anz_reference"], title: title)
for_code = Randd::Field.create(anz_reference: row["anz_reference"], title: row['title'])
counter += 1 if for_code.persisted?
end
puts "Imported #{counter} field codes"
end
end
当我尝试时
bundle exec rake import:randd_fields
我得到同样的错误:
bundle exec rake import:randd_fields
NameError: undefined local variable or method `randd_fields' for main:Object
from (irb):6
【问题讨论】:
-
试试 RanndField 作为类名。
-
我应该在哪里写那个汤姆?你的意思是:for_code = RanddField.create 在 import.rake 文件中?
-
作为你的类名而不是 Randd::Field
-
嗨,汤姆 - 不,那是不正确的。资源字段在 Randd 文件夹内命名空间,所以模型名称是正确的我有它的方式。还是谢谢。
-
我明白了。对不起。如果你还没有得到答案,我明天晚上再看。
标签: ruby-on-rails ruby csv import