2014-10-14 3 views
1

컨트롤러에 export_csv 메소드가 있습니다.레일 4 ... send_data 후 페이지 새로 고침

def export_csv 
    if params[:from_date].present? && params[:to_date].present? 
    @users = User.where("created_at between ? and ?", params[:from_date], params[:to_date]) 
     if [email protected]? 
      users_csv = User.to_excel(@users) 
      send_data(users_csv, :type => 'text/csv', :filename => 'users.csv') 
      flash.now[:success] = "Successfully downloaded the report!" 
     else 
     flash.now[:notice] = "No records over selected duration!" 
     end 
    else 
    flash.now[:notice] = "Select from and to date.." 
    end 
end 

파일을 다운로드했지만 페이지를 새로 고치거나 다시로드하지 않았습니다. 이로 인해 플래시 메시지는 파일을 다운로드 한 후에도 페이지에 남아있게됩니다.

나는 소수의 사이트를 통과했으며 send_data가 자동으로보기를 렌더링하므로 다른 리디렉션 또는 렌더링을 사용할 수 없음을 알았습니다.

send_data 이후에 페이지를 다시로드하는 방법이 있습니까?

답변

1

send_data은 전체 서버 응답을 설정하므로 브라우저는 웹 페이지가 아닌 CSV 파일을 수신 중입니다. 이것이 플래시 메시지가 표시되지 않는 이유입니다. 대안은 (임의의 이름으로) 임시 CSV 파일을 생성하고 여기에 링크를 다시 제공 될 수있다 : 물론

def export_csv 
    if params[:from_date].present? && params[:to_date].present? 
    @users = User.where("created_at between ? and ?", params[:from_date], params[:to_date]) 
     if [email protected]? 
      #Create temporary CSV report file and get the path to it. 
      csv_file_path = create_csv_file(User.to_excel(@users)) 

      #Change the flash message a bit for requesting the user 
      #to click on a link to download the file.     
      flash.now[:success] = "Your report has been successfully generated! Click <a href='#{csv_file_path}'>here</a> to download".html_safe 
     else 
     flash.now[:notice] = "No records over selected duration!" 
     end 
    else 
    flash.now[:notice] = "Select from and to date.." 
    end 
end 

당신이 기능 create_csv_file를 구현해야합니다. 서버에 오래된 파일을 보관하지 않으려면 download_report이라는 파일을 읽고 클라이언트에게 send_data으로 다시 보내고 마지막으로 삭제하는 등의 새로운 방법을 구현할 수 있습니다. 위에서 언급 한 기능

편집

의사 코드 : 답장을

require 'tempfile' 

def create_csv_file(data)  
    #Create a temporary file. If you omit the second argument of Tempfile.new 
    #then the OS's temp directory will be used. 
    tmp = Tempfile.new('report', 'my/temp/dir') 
    tmp.write(data) 
    tmp.close 

    return tmp.path 
end 


#Method in controller for downloading the file. I omit checks and/or security issues. 
def download_report 
    #Warning: a mechanism should be implemented to prevent the remote 
    #client from faking the path and download other files. 
    #A possible solution would be providing not only the file path but also a 
    #hash with a secret key to validate the path. Function create_csv_file() 
    #should, then, return a hash in addition of a path. 

    path = params[:report] 
    file = File.open(path, "rb") 
    contents = file.read 
    file.close 

    send_data(contents , :type => 'text/csv', :filename => 'users.csv')  
    file.unlink #Delete file 
end 
+0

감사합니다. 그것을 할 다른 방법이 없습니까? 배경 작업을 사용하여 파일을 삭제하는 것은 대단한 일일 것입니다. –

+0

음, send_data (파일 내용을 먼저 읽음)를 사용하는 새 메소드'download_csv'를 생성 한 다음 파일을 삭제할 수 있습니다. – Claudix

+0

create _ csv _ file에 쓰여진 내용과 _ report를 다운로드 할 수있는 의사 코드를 도울 수 있습니까? –