【问题标题】:Using will_paginate with array routing issue将 will_paginate 与数组路由问题一起使用
【发布时间】:2018-08-24 12:20:37
【问题描述】:

我的项目当前配置为只有一个视图import.html,允许用户上传和查看 CSV 文件的内容(上传后)。

这里是控制器类的导入方法:

class UploadController < ApplicationController
  require "CSV"
  require 'will_paginate/array'
  def import
    return if params[:file] == nil
    file = params[:file]
    @table = []
    rowi = 0

    CSV.foreach(file.path) do |row|
      if rowi == 0 #and headers (for later)
        @headers = row
      else
        @table << row.join("~")
      end
      rowi = rowi + 1
    end

    @table = @table.paginate(page: params[:page], :per_page => 20)
    session
  end
end

这里是视图:

<h1>Upload#import</h1>

<h4>UPLOAD A CSV FILE:</h4>

<%= form_tag({:action => "import"}, multipart: true) do %>
  <%= file_field_tag :file %>
  <%= submit_tag( "Import" ) %>
<% end %>

<% if @headers and @table %>
  <h1>RESULTS</h1>
  <table>
    <thead>
      <tr>
        <% @headers.each do |column| %>
          <td><%= column  %></td>
        <% end %>
      </tr>
    </thead>
    <tbody>
      <% @table.each do |row| %>
        <tr>
          <% row.split("~").each do |cell| %>
            <td><%= cell %></td>
          <% end %>
        </tr>
      <% end %>
    </tbody>
  </table>
  <%= will_paginate @table, inner_window: 1, outer_window: 0%>
<% end %>

路线如下:

Rails.application.routes.draw do
  root 'upload#import'
  post "/" => "upload#import"
end

当与我的表格交互以转到不同的页面时,我的路线没有指定指令:

GET "/?page=(pagenumber)"

我不知道该怎么告诉它才能显示正确的页面。

它只是默认重定向到import_page,它会清除所有已导入的数据。我应该如何解决这个问题?

【问题讨论】:

  • 您确实应该为post 请求提供单独的路由来上传和保存文件,并在get 请求中显示内容。基本上,您会将保存文件的代码拆分为post 操作,并将表生成拆分为get。然后get 页面的表单将点击post 操作,如果成功,它将重定向回get 端点。
  • 表生成并没有真正委托给一个动作。你能评论一下我的路线会是什么样子吗?我是否需要添加另一个视图来处理分页结果?
  • 我添加了一个答案,涵盖了创建和显示资源的基本结构。告诉我它有什么帮助!

标签: ruby routes ruby-on-rails-5 will-paginate


【解决方案1】:

简而言之,您可能希望为此使用singular resource。

所以你需要以下内容:

在routes.rb:

resource :uploader, only: [:show, :create]

(注意,这与更常见的resources 复数不同。)

这将为您提供以下路线:

POST    /upload uploads#create  # create the new upload
GET     /upload uploads#show    # display the one and only upload resource

在您的控制器中:

class UploadController < ApplicationController
  require "csv"
  require 'will_paginate/array'

  def create
    return if params[:file] == nil
    file = params[:file]
    @table = []
    rowi = 0

    CSV.foreach(file.path) do |row|
      if rowi == 0 #and headers (for later)
        @headers = row
      else
        @table << row.join("~")
      end
      rowi = rowi + 1
    end

    # save the file to the db
    # redirect to upload_path
  end

  def show   
    # Find the relevant table 
    @table = Table.last.paginate(page: params[:page], :per_page => 20)
  end
end

然后你会想要在你的视图中修改表单以使用@table,类似于:

...
<%= form_for @table, multipart: true) do %>
  <%= f.file_field :file %>
  <%= f.submit  "Import" %>
<% end %>
...

这是对您的项目应该如何工作的非常基本的总结。关键在于使用正确的单独操作来创建和显示表格。

您可能希望了解使用 strong params 和其他 Rails 约定。

最后,如果有帮助,请查看生成的 Rails 控制器(即 rails generate controller my_example_controller) - 这将预先构建 create 和 show 操作,您可以查看将代码合并到某些东西中类似。

希望这会有所帮助 - 如果您有任何问题,请大声告诉我。

【讨论】:

  • 有没有办法在不使用数据库的情况下做到这一点?通常,我要上传的 csv 文件有数万行。我需要将文件内容存储在变量中。你能解释一下@table = Table.last这行的含义吗? ....
  • 简而言之,这并不能真正解决我的问题。我只是希望能够显示分页 array 的所有页面。编辑我的应用程序以使用单个资源完成了所有工作,但使它工作。
  • 这绝对是可能的,但您可能需要使用 Javascript 和/或Ajax 来处理上传文件并将其呈现在页面上。以这种方式存储如此大的文件可能会占用大量内存。您是否有理由反对将数据存储在数据库中?您是否有更多关于可以添加到问题中以帮助解决此问题的数据格式的信息?
  • 我反对,因为有时 csv 中可能有数百万行,将它们插入表中会很耗时。无需将文件存储在数据库中。上传信息的目的是使用 API 更新外部数据库。我只是希望能够提供一个小的 UI 来帮助用户感觉可以使用 API。
  • OK 很酷——我认为使用 Ajax 将完成您之后的工作。您可以使用与答案类似的格式,仅在 POST 操作中以 JSON 格式呈现数据,并在成功时显示。
猜你喜欢
  • 2010-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-03
  • 2016-09-18
  • 2015-03-25
  • 2010-11-08
  • 2019-10-25
相关资源
最近更新 更多