简体   繁体   English

重定向到具有大数据的另一个端点 - Rails/Ruby

[英]Redirect to another endpoint with large data - Rails/Ruby

I have a doubt about showing a generated CSV file to the user (with a large amount of data).我对向用户显示生成的 CSV 文件(包含大量数据)存有疑问。 So here is the task I have to do.所以这是我必须做的任务。

App: I have a film that has many characters. App:我有一部有很多角色的电影。

Task:任务:

  • allow users to upload characters via CSV (ok, done)允许用户通过 CSV 上传字符(好的,完成)
  • if there are errors, show them for each row (ok, done)如果有错误,为每一行显示它们(好的,完成)
  • in the results page, also show a link to a new CSV file only with the remaining characters - the ones that couldn't be created ( I'm stuck here )在结果页面中,还显示一个新的 CSV 文件的链接,仅包含剩余字符 - 无法创建的字符(我被困在这里)

Here is part of my code (upload method):这是我的部分代码(上传方法):

def upload
    saved_characters = []
    characters_with_errors = []
    errors = {}

    begin
      CSV.parse(params[:csv].read, **csv_options) do |row|
        row_hash = clear_input(row.to_h)
        new_character = Character.new(row_hash)

        if new_character.save
          add_images_to(new_character, row)
          saved_characters << new_character
        else
          characters_with_errors << new_character
          errors[new_character.name] = new_character.errors.full_messages.join(', ')
        end
      end
    rescue CSV::MalformedCSVError => e
      errors = { 'General error': e.message }.merge(errors)
    end

    @upload = {
      errors: errors,
      characters: saved_characters,
      characters_with_errors: characters_with_errors
    }
  end

The issue: large amount of data问题:数据量大

In the end, the upload.html.erb almost everything works fine, it shows the results and errors per column BUT I'm not sure how create a link on this page to send the user to the new CSV file (only with characters with errors).最后, upload.html.erb几乎一切正常,它显示了每列的结果和错误但我不确定如何在此页面上创建链接以将用户发送到新的 CSV 文件(仅包含字符错误)。 If the link sends the user to another method / GET endpoint (for the view with CSV format), how can I send such a large amount of data (params won't work because they will get too long)?如果链接将用户发送到另一个方法/GET 端点(对于 CSV 格式的视图),我如何发送如此大量的数据(参数将无法工作,因为它们会变得太长)? What would be the best practice here?这里的最佳做法是什么?

You can use a session variable to store the data, and then redirect to a new action to download the file.您可以使用一个 session 变量来存储数据,然后重定向到一个新的操作来下载文件。 In the new action, you can get the data from the session variable, and then generate the CSV file.在new action中,可以从session变量中获取数据,然后生成CSV文件。

For example, In the upload action, you can do something like this:例如,在上传操作中,您可以执行以下操作:

session[:characters_with_errors] = characters_with_errors

redirect_to download_csv_path

In the download_csv action, you can do something like this:在 download_csv 操作中,您可以执行以下操作:

characters_with_errors = session[:characters_with_errors]

session[:characters_with_errors] = nil

respond_to do |format|
  format.csv { send_data generate_csv(characters_with_errors) }
end

In the generate_csv method, you can do something like this:在 generate_csv 方法中,你可以这样做:

def generate_csv(characters_with_errors)
  CSV.generate do |csv|
    csv << ['name', 'age' ]
    characters_with_errors.each do |character|
      csv << [character.name, character.age]
    end
  end
end

Another option, you can use a temporary file to store the data and then send the user to the new CSV file.另一种选择,您可以使用临时文件来存储数据,然后将用户发送到新的 CSV 文件。 Here is an example:这是一个例子:

  def upload
      saved_characters = []
      characters_with_errors = []
      errors = {}
  
      begin
        CSV.parse(params[:csv].read, **csv_options) do |row|
          row_hash = clear_input(row.to_h)
          new_character = Character.new(row_hash)
  
          if new_character.save
            add_images_to(new_character, row)
            saved_characters << new_character
          else
            characters_with_errors << new_character
            errors[new_character.name] = new_character.errors.full_messages.join(', ')
          end
        end
      rescue CSV::MalformedCSVError => e
        errors = { 'General error': e.message }.merge(errors)
      end
  
      @upload = {
        errors: errors,
        characters: saved_characters,
        characters_with_errors: characters_with_errors
      }
  
      respond_to do |format|
        format.html
        format.csv do
          # Create a temporary file
          tmp = Tempfile.new('characters_with_errors')
          # Write the CSV data to the temporary file
          tmp.write(characters_with_errors.to_csv)
          # Send the user to the new CSV file
          send_file tmp.path, filename: 'characters_with_errors.csv'
          # Close the temporary file
          tmp.close
        end
      end
    end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM