Rails 5 - 如何上传excel文件 - 教程不工作
我想上传一个excel文件到我的Rails 5应用程序。Rails 5 - 如何上传excel文件 - 教程不工作
我试过this教程,还有this一,this一。我无法让他们工作。
我叫一个命名空间中的模型:
class Randd::Field < ApplicationRecord
require 'csv'
我已经在我的模型尝试每一种方法:
def self.import(file)
CSV.foreach(file.path, headers: true) do | row |
Randd::Field.create! row.to_hash
end
end
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
randd_field_hash = row.to_hash # exclude the price field
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::Field.create!(product_hash)
end # end if !product.nil?
end # end CSV.foreach
end # end self.import(file)
在我的控制,我有:
类的RandD: :FieldsController < ApplicationController
def index
@randd_fields = Randd::Field.all
end
def new
@field = Randd::Field.new
end
def import
Randd::Field.import(params[:file])
redirect_to root_path, notice: "Data imported"
end
end
层
控制器上的注意事项:
- 我没有任何强烈PARAMS - 这似乎很奇怪,我,但没有一个教程似乎表明他们是必需的。
- 我做了上面的新动作,因为我试图制作一个单独的表单来上传文件,而不是使用索引动作来保存文件。我已尝试使用新的以及使用教程中列出的表单字段在索引视图中列出的过程。这两种方法都无效。
在我的路线,我有:
namespace :randd do
resources :fields do
collection do
post :import
end
end
end
在我的形式,我有:
<%= simple_form_for [:randd, @field], multipart: true do |f| %>
<div class="form-inputs">
<%= f.file_field :file %>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
当我尝试用新的观点来上传文件,我得到一个错误,说:
undefined method `randd_randd_fields_path' for #<#<Class:0x007fd5edf73738>:0x007fd5f698f430>
Did you mean? randd_fields_path
,当我尝试使用索引视图来保存表单字段,我有:
<%= form_tag import_randd_fields_path, multipart: true do |f| %>
<%= f.file_field :file %>
<%= submit_tag 'Import' %>
<% end %>
当我尝试使用索引视图上传的文件,我得到一个错误,指出:
undefined method `file_field' for nil:NilClass
谁能推荐另一教程如何上传excel文件到轨道5.我可能使用的是太旧 - 但我找不到更好的帮助来源。
下一次尝试
我设法呈现与下面的建议的形式:
<%= simple_form_for (@field), multipart: true do |f| %>
我必须定义节目,为了让这个过程创造我的田地控制器动作跑。我加入到我的RandD域控制器,所以它现在有:
class Randd::FieldsController < ApplicationController
def index
@randd_fields = Randd::Field.all
end
def new
@field = Randd::Field.new
end
def create
redirect_to action: "import"
end
def show
redirect_to action: "index"
end
def import
Randd::Field.import(params[:file])
redirect_to action: "index", notice: "Data imported"
end
end
当我经历的过程,上传文件并提交,我可以在日志中看到这种情况出现:
Started GET "/images/upload/cache/presign?extension=.xls&_=142388" for ::1 at 2016-11-14 10:50:12 +1100
Started POST "/randd/fields" for ::1 at 2016-11-14 10:50:12 +1100
Processing by Randd::FieldsController#create as JS
Parameters: {"utf8"=>"✓", "authenticity_token"=>"8vJ7bA==", "randd_field"=>{"file"=>"{\"id\":\"04f4e0679f2a562.xls\",\"storage\":\"cache\",\"metadata\":{\"size\":165376,\"filename\":\"FOR codes.xls\",\"mime_type\":\"\"}}"}}
Redirected to http://localhost:3000/randd/fields/import
Completed 200 OK in 43ms (ActiveRecord: 0.0ms)
Started POST "/randd/fields" for ::1 at 2016-11-14 10:50:13 +1100
Processing by Randd::FieldsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"8v+bbA==", "commit"=>"Create Field"}
Redirected to http://localhost:3000/randd/fields/import
Completed 302 Found in 40ms (ActiveRecord: 0.0ms)
Started GET "/randd/fields/import" for ::1 at 2016-11-14 10:50:13 +1100
Processing by Randd::FieldsController#show as HTML
Parameters: {"id"=>"import"}
Redirected to http://localhost:3000/randd/fields
Completed 302 Found in 29ms (ActiveRecord: 0.0ms)
Started GET "/randd/fields/import" for ::1 at 2016-11-14 10:50:13 +1100
Started GET "/randd/fields" for ::1 at 2016-11-14 10:50:13 +1100
Processing by Randd::FieldsController#show as HTML
Parameters: {"id"=>"import"}
Redirected to http://localhost:3000/randd/fields
Completed 302 Found in 32ms (ActiveRecord: 0.0ms)
Processing by Randd::FieldsController#index as HTML
Rendering randd/fields/index.html.erb within layouts/application
Randd::Field Load (1.6ms) SELECT "randd_fields".* FROM "randd_fields"
Rendered randd/fields/index.html.erb within layouts/application (46.9ms)
User Load (1.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 4], ["LIMIT", 1]]
Setting Load (1.0ms) SELECT "settings".* FROM "settings" WHERE "settings"."user_id" = $1 LIMIT $2 [["user_id", 4], ["LIMIT", 1]]
Rendered layouts/nav/_inner.html.erb (93.3ms)
Completed 200 OK in 2773ms (Views: 2732.5ms | ActiveRecord: 4.4ms)
Started GET "/randd/fields" for ::1 at 2016-11-14 10:50:16 +1100
Processing by Randd::FieldsController#index as HTML
Rendering randd/fields/index.html.erb within layouts/application
Randd::Field Load (0.9ms) SELECT "randd_fields".* FROM "randd_fields"
但是 - - 这不起作用,因为表格是空的。它没有实例。
COURT3NAY的建议
的建议是我在交换领域控制器导入操作来创建操作的内容。我现在控制器有:
class Randd::FieldsController < ApplicationController
def index
@randd_fields = Randd::Field.all
end
def new
@field = Randd::Field.new
end
def create
Randd::Field.import(params[:file])
redirect_to action: "index", notice: "Data imported"
# @field = Randd::Field.new(randd_field_params)
# redirect_to action: "import"
end
def show
redirect_to action: "index"
end
# def import
# # byebug
# Randd::Field.import(params[:file])
# redirect_to action: "index", notice: "Data imported"
# end
private
def randd_field_params
params.fetch(:randd_field, {}).permit(:title, :anz_reference)
end
end
我的形式现在有(我删除了进口URL路径):
<%= simple_form_for (@field), multipart: true do |f| %>
<%= f.error_notification %>
<div class="form-inputs" style="margin-bottom: 50px">
<div class="row">
<div class="col-md-12">
<div class="form_title">Research Field Codes</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<%= f.file_field :file %>
</div>
</div>
</div>
<div class="row">
<div class="col-md-10 col-md-offset-1" style="margin-top: 50px">
<div class="form-actions">
<%= f.button :submit %>
</div>
</div>
</div>
<% end %>
错误现在说:
The action 'import' could not be found for Randd::FieldsController
错误消息突出问题用我自己写的代码。
def process(action, *args)
@_action_name = action.to_s
unless action_name = _find_action_name(@_action_name)
raise ActionNotFound, "The action '#{action}' could not be found for #{self.class.name}"
end
我认为它是一个问题,但因为我没有一个导入动作了。我应该创建一个以前导入的东西(根据教程)。
我的猜测在获得解决此:
我寻找,我仍然要求“进口”。我在两个地方使用它,所以我尝试在两者中交换“导入”以创建。现在
,我的模型有:
def self.create(file)
CSV.foreach(file.path, headers: true) do |row|
randd_field_hash = row.to_hash # exclude the price field
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::Field.create! row.to_hash#(randd_field_hash)
end # end if !product.nil?
end # end CSV.foreach
end # end self.import(file)
的创建操作在我的控制器有:
def create
Randd::Field.create(params[:file])
redirect_to action: "index", notice: "Data imported"
# @field = Randd::Field.new(randd_field_params)
# redirect_to action: "import"
end
这个猜测犯规解决任何问题,但。我仍然收到一条错误消息:
undefined method `path' for nil:NilClass
我也不知道这是什么意思。
你真的很接近。 您需要发布才能导入。你刚开场#显示
Processing by Randd::FieldsController#show as HTML
Parameters: {"id"=>"import"}
您需要发布到域#导入
<%= simple_form_for (@field), url: import_fields_path, multipart: true do |f| %>
,或者只是使用#创建的,而不是重定向领域。一旦你发布到#create重定向将失去参数。
错误现在说:未定义的方法'路径'为零:NilClass。它突出显示了这一行:def self.import(file) CSV.foreach(file。路径,标题:true)do | row | – Mel
我假设CSV在某种程度上是xls的代名词。这可能是我的问题吗?也许我会按照说明使用Excel电子表格不起作用的东西。 – Mel
不,它意味着你的字段(params [:file])是空的。阅读错误 - 未定义的方法路径为零。你正在调用file.path,因此,文件是零。跟踪它 - 你调用Radd :: Field.import(params [:file]),所以params [:file]是零。所以你的表单发布nil params [:file]。为什么? – court3nay
你试过了吗?' – court3nay
是的 - 它加载表单,但它不工作与导入的数据创建记录 – Mel