Rails 5 - 如何上传excel文件 - 教程不工作 [英] Rails 5 - how to upload excel files - tutorials not working out
问题描述
我试图将excel文件上传到我的Rails 5应用程序。
I am trying to upload an excel file to my Rails 5 app.
我尝试过此教程和此< a> one和这一个。我不能让他们任何工作。
I have tried this tutorial, and this one, and this one. I can't get any of them to work.
我有一个命名空间模型名为:
I have a namespaced model called:
class Randd::Field < ApplicationRecord
require 'csv'
我在我的模型中尝试过这些方法: / p>
I have tried each of these methods in my model:
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)
在我的控制器中,我有:
In my controller, I have:
class Randd :: FieldsController< ApplicationController
class 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
b $ b
控制器上的注意事项:
Notes on the controller:
- 我没有任何强大的参数 -
- 我进行了上述新操作,因为我试图创建一个单独的表单来上传文件,而不是使用索引操作来保存文件。我已经尝试使用新的以及使用教程中概述的过程,其中表单字段在索引视图中设置。
在我的路线中,我有:
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 %>
当我尝试使用新视图上传文件时, #< Class:0x007fd5edf73738>:0x007fd5f698f430> $ p
When I try using the new view to upload the file, I get an error that says:
undefined method `randd_randd_fields_path' for #<#<Class:0x007fd5edf73738>:0x007fd5f698f430>
Did you mean? randd_fields_path
当我尝试使用索引视图来保存表单字段时,我有:
When I try using the index view to hold the form field, I have:
<%= form_tag import_randd_fields_path, multipart: true do |f| %>
<%= f.file_field :file %>
<%= submit_tag 'Import' %>
<% end %>
当我尝试使用索引视图来上传文件时, p>
When I try using the index view to upload the file, I get an error that says:
undefined method `file_field' for nil:NilClass
任何人都可以推荐另一个教程如何将excel文件上传到rails 5.可能我使用的是太旧 - 但我找不到更好的帮助源。
Can anyone recommend another tutorial for how to upload an excel file to rails 5. It's possible that the ones I'm using are too old - but I can't find a better source of help.
NEXT ATTEMPT
我设法让表单呈现建议如下:
I managed to get the form to render with the suggestion below:
<%= simple_form_for (@field), multipart: true do |f| %>
我必须在我的字段控制器中定义显示和创建操作,我添加到我的randd字段控制器,所以现在有:
I had to define show and create actions in my fields controller in order to let this process run. I added to my randd fields controller so it now has:
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
通过过程,上传文件并提交,我可以看到这发生在日志:
When I go through the process, upload the file and submit, I can see this happening in the log:
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"
但是 - 这没有工作,因为表是空的。没有实例。
But -- this didn't work because the table is empty. It has no instances.
COURT3NAY的建议
建议我换掉导入操作的内容控制器中的字段到创建操作。我的控制器现在有:
The suggestion is that I swap the content of the import action in the fields controller to the create action. My controller now has:
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
$ b b
我的表单现在有(我删除了导入网址路径):
My form now has (i removed the import url path):
<%= 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
错误消息强调了我没有写自己的代码的问题。
The error message highlights a problem with code that I didn't write myself.
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
我认为它的问题,因为我没有导入操作不再。
I think its a problem though because I don't have an import action anymore. I'm supposed to have create to do the things that were in import previously (per the tutorials).
我的指南在此之后:
我搜索了我仍然在要求'import'。我在两个地方使用它,所以我试图交换导入创建在两个。
I searched for where I was still asking for 'import'. I use it in two places, so I tried swapping 'import' for create in both.
现在,我的模型有:
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)
在我的控制器中的创建操作有:
The create action in my controller has:
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
这个猜测没有解决任何问题。我仍然得到一个错误消息,说:
This guess doesnt solve anything though. I still get an error message that says:
undefined method `path' for nil:NilClass
我也不知道这是什么意思。
I also don't know what that means.
推荐答案
你真的很近。
您需要发布导入。你只是得到字段#show
You're really close. You need to post to import. You're just getting fields#show
Processing by Randd::FieldsController#show as HTML
Parameters: {"id"=>"import"}
您需要发布到字段#import
You need to post to fields#import
<%= simple_form_for (@field), url: import_fields_path, multipart: true do |f| %>
或者,只需使用#create而不是重定向。一旦您发布到#create重定向将失去params。
or, just use fields#create instead of redirecting. Once you post to #create the redirect will lose the params.
这篇关于Rails 5 - 如何上传excel文件 - 教程不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!