我正在尝试将我保存在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:未定义的局部变量或方法`title&#39; for main:Object
任何人都可以看到我做错了吗?
我也尝试过本教程 How to import CSV files in Rails by Matt Morgante ,并试图将rails cast和Roo gem用于同一目的。这两个选项都不起作用--Rails Cast很旧,所以可能已经过时了,其他教程的帖子中的注释显示许多其他人无法使用这种方法 - 也许Rails中的东西已经改变了,因为它提出了。
GoRails论坛上建议问题可能归因于CSV文件未编码为UTF-8规范。有人建议,可以通过将数据传输到谷歌驱动器中的工作表,然后将其下载为csv以便与rails一起使用来解决这个问题。我试过这个。
我得到了与使用xls创建的文件运行rake任务时相同的错误。
ZHONG&#39; S建议
根据钟的建议,我尝试将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
答案 0 :(得分:1)
这里可能有两个问题。
在csv文件中编码。 ArgumentError: invalid byte sequence in UTF-8
未定义的局部变量。 NameError: undefined local variable or method 'randd_fields' for main:Object
我猜你正在尝试计算创建/导入的记录:
for_code = Randd::Field.create(anz_reference: row["anz_reference"], title: title)
counter += 1 if randd_field.persisted?
您创建的记录为for_code
,但是您正在检查randd_field
。
这应该解决它
counter +=1 if for_code.presisted?
<强>更新强>
$ bundle exec rake import:randd_fields --trace **调用import:randd_fields(first_time)**调用环境(first_time)**执行环境**执行导入:randd_fields nil rake aborted! NameError:未定义的局部变量或main:Object
的方法`title'
这是因为未定义title
变量。我想你想在这里使用row[]
。
for_code = Randd::Field.create(anz_reference: row["anz_reference"], title: row['title'])
更新2:
您的佣金任务名称中有拼写错误
更新3:
我认为你在rails console中调用了bundle exec rake import:randd_fields
。
直接在终端运行它应该修复它。