是的,这是可能的,而且您不需要 ActiveStorage。Rails 的基本文件上传功能就足够了。同时,Administrate 尝试遵循 Rails 约定,并为您提供挂钩来更改模板并引用您自己的控制器和操作,您可以在其中实现这一点。这是一个如何解决问题的示例。
首先,您需要添加一个带有文件字段的表单。管理员将能够使用它来上传 CSV。
有很多地方可以放置此表格。对于此示例,假设您要导入的是“产品”(模型Product
),并且您希望将链接放在索引页面中。
您可以用自己的模板覆盖 Administrate 自己的模板。以下命令将生成index
您可以自定义的模板副本,Administrate 将使用它来代替它自己的:
$ ./bin/rails g administrate:views:index
这将为您提供一个新文件app/views/admin/application/index.html.erb
。
更改它以添加指向将托管上传表单的单独页面的链接:
<% if page.resource_name == "product" %>
<div class="link-to-upload"><%= link_to "CSV Import", upload_admin_products_path %></div>
<% end %>
您可以将其放在页面标题和搜索栏之间。或者你想要的任何地方,真的。它执行以下操作:
- 检查我们在“产品”的
if
索引页面中,而不是其他的东西。
link_to
指向我们尚未创建的页面的链接,该页面将承载上传表单。
如果您现在加载产品索引页面,它将显示错误NameError
,并带有消息undefined local variable or method 'upload_admin_products_path'
。这是因为我们仍然没有新页面的路线。现在让我们添加它。
在路由文件config/routes.rb
中,您已经有了一个路由resources :products
。将其更改为如下所示:
resources :products do
collection do
get :upload, action: 'upload_form'
post :upload, action: 'upload_process'
end
end
这实际上增加了两条路线,而不是一条。一个用于表单页面,另一个用于处理上传的 CSV 的操作。
现在,您可以单击链接并转到新页面。它会再次破裂。这一次的错误将是 Unknown action - The action 'upload_form' could not be found for Admin::ProductsController
。那是因为我们还没有提供这个页面的视图。让我们现在就开始做吧。
在以下位置添加具有以下内容的视图app/views/admin/products/upload_form.html.erb
:
<header class="main-content__header" role="banner">
<h1 class="main-content__page-title" id="page-title">
Import products from CSV
</h1>
</header>
<section class="main-content__body main-content__body">
<%= form_for :products, html: { class: "form" } do |f| %>
<p><%= f.file_field(:file) %></p>
<p><%= f.submit "Upload" %></p>
<% end %>
</section>
现在您应该能够加载页面并查看表单。我添加了额外的标记(如那些header
和section
元素),使其看起来与 Administrate 提供的其他页面相似。
该表单有一个file_field
和一个提交按钮。提交时,它会将文件/admin/products/upload
作为 POST 请求发送到当前 URL ( )。它将由post
我们之前添加的路由在 action 上处理upload_process
。我们现在就写吧。
在控制器Admin::ProductsController
上,添加以下方法来实现动作:
def upload_process
file = params[:products][:file]
data = CSV.parse(file.to_io, headers: true, encoding: 'utf8')
# Start code to handle CSV data
ActiveRecord::Base.transaction do
data.each do |row|
Product.create(row.to_h)
end
end
# End code to handle CSV data
redirect_to admin_products_url
end
这将根据 CSV 中包含的内容创建新产品,然后将用户重定向回产品索引页面。
此示例操作非常简单,可能无法完全满足您的需求。您可能想复制您的代码seeds.rb
并将其粘贴在我的评论Start
和End
评论之间,以便它完全按照您的意愿行事。有很多可能性。