0

I am attempting to code a very simple way for a user to add html files to my Heroku app. These files would be saved in ./log for rendering later. I have tested my code locally (in both development and production), but when I attempt to upload a file on my Heroku hosted repo I get internal server error 500.

controller upload.rb:

class UploadController < ApplicationController
  def index
     render :file => 'upload/uploadfile.haml'
  end

  def uploadFile
    file_param = params[:upload][:datafile]
    post = DataFile.save(file_param)
    render :text => "File has been uploaded successfully"
  end
end

model data_file.rb:

class DataFile < ActiveRecord::Base
  def self.save(upload)
    # Changed Default Destination: [__RAILS_DIR__/log]
    name = "./log/" + upload.original_filename

    # can haz data directory?
    require 'FileUtils'
    FileUtils.mkdir_p(File.dirname(name))


    File.open(name, "wb") { |f| f.write(upload.read) }
  end
end

view uploadfile.haml:

%h1 File Upload
= form_for :upload,:url=>{:action => 'uploadFile'},:html => { :multipart => true } do |f|
  %p
    %label{:for => "upload_file"} Select File
    \:
    \#{f.file_field 'datafile'}
  = f.submit "Upload"

heroku logs:

2012-08-07T14:13:20+00:00 app[web.1]: Started POST "/uploadFile" for 69.29.117.99 at 2012-08-07 14:13:20 +0000
2012-08-07T14:13:20+00:00 app[web.1]: Processing by UploadController#uploadFile as HTML
2012-08-07T14:13:20+00:00 app[web.1]: Parameters: {"utf8"=>"✓", "authenticity_token"=>"1dAXkMulNR0d8S/l6QC8JnpSDtNBaHoyKJezgnheR10=", "upload"=>{"datafile"=>#>}, "commit"=>"Upload"}
2012-08-07T14:13:20+00:00 app[web.1]: Completed 500 Internal Server Error in 3ms
2012-08-07T14:13:20+00:00 app[web.1]: 
2012-08-07T14:13:20+00:00 app[web.1]: LoadError (no such file to load -- FileUtils):
2012-08-07T14:13:20+00:00 app[web.1]: app/models/data_file.rb:7:in save'
2012-08-07T14:13:20+00:00 app[web.1]: app/controllers/upload_controller.rb:8:inuploadFile'
2012-08-07T14:13:20+00:00 app[web.1]: 
2012-08-07T14:13:20+00:00 app[web.1]: 
2012-08-07T14:13:20+00:00 app[web.1]: cache: [POST /uploadFile] invalidate, pass

heroku: http://upload-example.herokuapp.com/

github: https://github.com/halterj1/upload

Please no trying to convince me to use paperclip or carrierwave, that does not answer my question. Any help would be greatly appreciated, thanks in advance guys!

JonahAaron
  • 398
  • 1
  • 9
  • see if this helps? http://stackoverflow.com/questions/3691746/heroku-file-upload-problem – GnrlBzik Aug 07 '12 at 14:44
  • did you read this one? https://devcenter.heroku.com/articles/read-only-filesystem – GnrlBzik Aug 07 '12 at 14:48
  • I re-read https://devcenter.heroku.com/articles/read-only-filesystem and I think I may have misunderstood the uses of ./log I also read up on https://devcenter.heroku.com/articles/s3 and if I understand right, using Amazon S3 will not allow me to use external html partials. Therefore I am now at a loss for how to accomplish external html partial uploading. – JonahAaron Aug 07 '12 at 15:21
  • does it need to be parsed by back end? may be ajax call can handle that on FED. What keeping you from using database? How big those html files can be in your assumption? Script removal? – GnrlBzik Aug 07 '12 at 16:41
  • Yes the html files need to be parsed as they will be used as partials in other app side pages (they will need to render html code). And I am not using my database because I would have no idea how to call a partial that was being stored in my database, or if that is even possible. – JonahAaron Aug 07 '12 at 19:17
  • is this partial be apart of layout level? – GnrlBzik Aug 07 '12 at 19:28
  • No, there would need to be at least two delegated partials, each one residing on a different page. The site would have many other pages and therefore using the partials in the layout would not be a viable option. – JonahAaron Aug 08 '12 at 01:03

1 Answers1

0

You should read this article on heroku: https://devcenter.heroku.com/articles/read-only-filesystem

edit:

As stated in article.

Your app is compiled into a slug for fast distribution across the dyno manifold. The filesystem for the slug is read-only, which means you cannot dynamically write to the filesystem for semi-permanent storage. The following types of behaviors are not supported:

  • Caching pages in the public directory
  • Saving uploaded assets to local disk (e.g. with attachment_fu or paperclip)
  • Writing full-text indexes with Ferret
  • Writing to a filesystem database like SQLite or GDBM
  • Accessing a git repo for an app like git-wiki

There are two directories that are writeable: ./tmp and ./log (under your application root). If you wish to drop a file temporarily for the duration of the request, you can write to a filename like #{RAILS_ROOT}/tmp/myfile_#{Process.pid}. There is no guarantee that this file will be there on subsequent requests (although it might be), so this should not be used for any kind of permanent storage.

Community
  • 1
  • 1
GnrlBzik
  • 3,358
  • 5
  • 27
  • 37
  • Although this does not provide a solution to my problem, I realized after reading the link (again) that Heroku never intended for people to do what I am trying to do. So either I will have to host somewhere else or find an alternative to file uploading. – JonahAaron Aug 07 '12 at 19:20
  • Thank you, but I did not know how else to phrase besides just giving a link to resource that explains this. – GnrlBzik Aug 07 '12 at 19:34
  • added snippet from the article just to make this answer more relevant. – GnrlBzik Aug 07 '12 at 19:40