Uploading a File in Rails

Uploading a file in Rails

Update 2018

While everything written below still holds true, Rails 5.2 now includes active_storage, which allows stuff like uploading directly to S3 (or other cloud storage services), image transformations, etc. You should check out the rails guide and decide for yourself what fits your needs.


While there are plenty of gems that solve file uploading pretty nicely (see https://www.ruby-toolbox.com/categories/rails_file_uploads for a list), rails has built-in helpers which make it easy to roll your own solution.

Use the file_field-form helper in your form, and rails handles the uploading for you:

<%= form_for @person do |f| %>
<%= f.file_field :picture %>
<% end %>

You will have access in the controller to the uploaded file as follows:

uploaded_io = params[:person][:picture]
File.open(Rails.root.join('public', 'uploads', uploaded_io.original_filename), 'wb') do |file|
file.write(uploaded_io.read)
end

It depends on the complexity of what you want to achieve, but this is totally sufficient for easy file uploading/downloading tasks. This example is taken from the rails guides, you can go there for further information: http://guides.rubyonrails.org/form_helpers.html#uploading-files

How to upload a file in rails?

Usually gems/plugins are used to to handle file uploads. My favorite one, and perhaps the most ubiquitous is Paperclip.

In your view, you'll have to tell the rails form helpers that you're uploading a file like this:

<%= form_for @model, :html => { :multipart => true } do |form| %>

how to upload files in rails

If your goal is to upload a file to a directory you shouldn't have to use Carrierwave or Paperclip. Those gems have a lot of support for image processing and extra options.

I suggest you look at the Ruby file class and the open method to be more specific. http://www.ruby-doc.org/core-1.9.3/File.html#method-c-open

Something like the following should do the trick:

# "public/csv" is the directory you want to save the files in
# upload["datafile"] is the data populated by the file input tag in your html form
path = File.join("public/csv", upload["datafile"].original_filename)
File.open(path, "wb") { |f| f.write(upload["datafile"].read) }

Keep in mind, your public directory is accessible to the world. If you need to save these in a more private location, make sure the directory is only readable and writable by your app.

Also, if you are working with CSV files, be sure to read through the Ruby CSV class: http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV.html. It makes working with CSV files a breeze.

Uploading File into Server and store the path in database in Ruby on Rails

db/migrate/20110711000004_create_files.rb

class CreateFiles < ActiveRecord::Migration
def change
create_table :files do |t|
t.string :name
# If using MySQL, blobs default to 64k, so we have to give
# an explicit size to extend them
t.binary :data, :limit => 1.megabyte
end
end
end

app/controllers/upload_controller.rb

 class UploadController < ApplicationController
def get
@file = File.new
end
end

app/views/upload/get.html.erb

<% form_for(:file,
url: {action: 'save'},
html: {multipart: true}) do |form| %>
Upload your file: <%= form.file_field("uploaded_file") %><br/>
<%= submit_tag("Upload file") %>
<% end %>

app/models/file.rb

class File < ActiveRecord::Base
def uploaded_file=(file_field)
self.name = base_part_of(file_field.original_filename)
self.data = file_field.read
end
def base_part_of(file_name)
File.basename(file_name).gsub(/[^\w._-]/, '')
end
end

app/controllers/upload_controller.rb

def save
@file = File.new(params[:file])
if @file.save
redirect_to(action: 'show', id: @file.id)
else
render(action: :get)
end
end

app/controllers/upload_controller.rb

def file
@file = File.find(params[:id])
send_data(@File.data,
filename: @File.name,
disposition: "inline")
end

app/controllers/upload_controller.rb

def show
@file = File.find(params[:id])
end

app/views/upload/show.html.erb

<h3><%= @file.name %></h3>
<img src="<%= url_for(:action => 'file', :id => @file.id) %>"/>

simple file upload in Rails doesn't work

This solution worked for me (reference).

Controller: Changed the saving directory from public to public/uploads. Used Rails.root to do the join of the path.

def upload
uploaded_io = params[:file]
File.open(Rails.root.join('public', 'uploads',uploaded_io.original_filename), 'wb') do |file|
file.write(uploaded_io.read)
respond_to do |format|
format.html { redirect_to(root_url, :notice => 'File was uploaded.') }
end
end
end

Form: Changed the form_for to form_tag

=form_tag({action: :upload}, multipart: true) do
= file_field_tag 'file'
= submit_tag 'Upload'

Routes:

root :to => "pages#index"
resources :pages do
collection {post :upload}
end

Ruby Rails: Upload File

It looks like params[:upload] isn't what you think it is. You forgot to set the form to be multipart. If fixing that doesn't make it work, start inspecting params to see what you're actually getting.

def uploadfile
puts params.inspect # Add this line to see what's going on
post = DataFile.save(params[:upload])
render :text => "File has been uploaded successfully"
end

Also, it's not a great "answer," but I've had good success using paperclip to handle file uploads. If you just want something that works (rather than learning how to do it yourself), check into that.



Related Topics



Leave a reply



Submit