是的,这是可能的,而且您不需要 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 和一个提交按钮。提交时,它将文件作为 POST 请求发送到当前 URL (/admin/products/upload)。它将由我们之前添加的post 路由在操作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 cmets 之间,这样它就可以完全按照您的要求进行操作。有很多可能性。