Rails Save Uploaded File to Local Directory
Ruby-red on Rails two.i - File Uploading
You lot may have a requirement in which yous want your site visitors to upload a file on your server. Runway makes it very easy to handle this requirement. At present, we volition proceed with a simple and small Track project.
As usual, let's start off with a new Rails awarding chosen upload. Let's create a basic structure of the application by using uncomplicated rails command.
C:\ruby> rails -d mysql upload
Let's decide where you would like to salvage your uploaded files. Assume this is data directory inside your public section. So, create this directory and check the permissions.
C:\cerise> cd upload C:\ruby-red\upload> mkdir upload\public\data
Our next stride volition exist as usual, to create controller and models.
Creating the Model
As this is not a database-based application, we can keep whatever proper name is comfortable to us. Assume we have to create a DataFile model.
C:\ruby\upload> reddish script/generate model DataFile exists app/models/ exists test/unit/ exists test/fixtures/ create app/models/data_file.rb create examination/unit of measurement/data_file_test.rb create test/fixtures/data_files.yml create db/migrate create db/migrate/001_create_data_files.rb
Now, we volition create a method called salve in data_file.rb model file. This method will be called by the application controller.
class DataFile < ActiveRecord::Base def self.save(upload) name = upload['datafile'].original_filename directory = "public/data" # create the file path path = File.bring together(directory, proper noun) # write the file File.open(path, "wb") { |f| f.write(upload['datafile'].read) } finish end
The above function will accept the CGI object upload and will extract the uploaded file name using the helper function original_filename and finally, it will store the uploaded file into the "public/data" directory. You can call the helper part content_type to know the media blazon of the uploaded file.
Here File is a ruby object and join is a helper role that volition concatenate the directory proper name forth with the file name and will return the full file path.
Next, to open a file in write mode, nosotros are using the open helper office provided by the File object. Further, we are reading data from the passed information file and writing into output file.
Creating Controller
Now, let's create a controller for our upload project −
C:\ruby\upload> ruby script/generate controller Upload exists app/controllers/ exists app/helpers/ create app/views/upload exists examination/functional/ create app/controllers/upload_controller.rb create test/functional/upload_controller_test.rb create app/helpers/upload_helper.rb
Now, we volition create two controller functions. The kickoff function index will call a view file to take user input, and the second function uploadFile takes file information from the user and passes it to the 'DataFile' model. We set the upload directory to the 'uploads' directory we created earlier "directory = 'data'".
class UploadController < ApplicationController def index render :file => 'app\views\upload\uploadfile.html.erb' end def uploadFile post = DataFile.save( params[:upload]) render :text => "File has been uploaded successfully" end end
Here, nosotros are calling the part defined in the model file. The return role is beingness used to redirect to view file as well equally to display a message.
Creating View
Finally, we will create a view file uploadfile.rhtml, which we take mentioned in the controller. Populate this file with the following code −
<h1>File Upload</h1> <% form_tag ({:activity => 'uploadFile'}, :multipart => truthful) practice %> <p><label for="upload_file">Select File</label> : <%= file_field 'upload', 'datafile' %></p> <%= submit_tag "Upload" %> <% end %>
Here everything is same what nosotros have explained in the earlier capacity. The simply new tag is file_field, which will create a push button to select a file from user's computer.
By setting the multipart parameter to true, yous ensure that your action properly passes along the binary data from the file.
Here, an of import indicate to note is that nosotros have assigned "uploadFile" as the method proper noun in :action, which will be called when yous click the Upload button.
It will evidence you a screen as follows −
Now, you select a file and upload it. This file will be uploaded into app/public/data directory with the actual file proper name and a message will exist displayed maxim that "File has been uploaded successfully".
Notation − If a file with the same name already exists in your output directory, then it will be overwritten.
Files Uploaded from Internet Explorer
Internet Explorer includes the entire path of a file in the filename sent, and so the original_filename routine will render something like −
C:\Documents and Files\user_name\Pictures\My File.jpg
Instead of just −
My File.jpg
This is easily handled by File.basename, which strips out everything before the filename.
def sanitize_filename(file_name) # get only the filename, not the whole path (from IE) just_filename = File.basename(file_name) # replace all none alphanumeric, underscore or perioids # with underscore just_filename.sub(/[^\w\.\-]/,'_') end
Deleting an Existing File
If you lot desire to delete whatsoever existing file, it is quite simple. All that you demand to exercise is write the following lawmaking −
def cleanup File.delete("#{RAILS_ROOT}/dirname/#{@filename}") if File.exist?("#{RAILS_ROOT}/dirname/#{@filename}") end
For a complete detail on File object, you demand to go through our Ruby Reference Transmission.
Source: https://www.tutorialspoint.com/ruby-on-rails-2.1/rails-file-uploading.htm