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!
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.