Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to upload a file in ruby on rails?

Tags:

I’m very new in ruby on rails. I’m stuck with a problem. I want to make a file upload functionality through which I can upload any kind of file (text,image etc.). My controller file is (upload_controller.rb):

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

My Model file is (data_file.rb):

class DataFile < ActiveRecord::Base
    attr_accessor :upload
  def self.save(upload)
    name = upload['datafile'].original_filename
    directory = 'public/data'
    # create the file path
    path = File.join(directory,name)
    # write the file
    File.open(path, "wp") { |f| f.write(upload['datafile'].read)}
  end
end

My View file is (uploadfile.html.erb):

<h1>File Upload</h1>
<%= form_tag({:action => 'uploadFile'}, :multipart => true) do %>
<p><label for="upload_file">Select File</label>
<%= file_field 'upload', 'datafile' %></p>
<%= submit_tag "Upload" %>
<% end %>

Now when I try to upload image then I'm getting error "invalid access mode wp" in model file. When I change File.open(path, "wp") to File.open(path, "w") in model file this give error "'\x89' from ASCII-8BIT to UTF-8". For .txt file, It works fine. I'm using ruby 1.9.3 and rails 3.2.6

like image 300
Vivacity InfoTech Avatar asked Jul 05 '12 10:07

Vivacity InfoTech


People also ask

How do I upload a file using curl?

How to send a file using Curl? To upload a file, use the -d command-line option and begin data with the @ symbol. If you start the data with @, the rest should be the file's name from which Curl will read the data and send it to the server. Curl will use the file extension to send the correct MIME data type.


2 Answers

Thank you for example, I study rails too!

It works in rails 3.1

My code:

Routes
resources :images do
      collection { post :upload_image }
    end

Controller

class ImagesController < ApplicationController
  def index
    @car = Car.find(params[:car_id])
    @images = @car.images.order("order_id")
  end

  def upload_image   
    DataFile.save_file(params[:upload])
    redirect_to images_path(:car_id => params[:car_id])
  end

View index.html.erb

<h1>File Upload</h1>
  <%= form_tag({:action => 'upload_image', :car_id => @car.id}, :multipart => true) do %>
    <p><label for="upload_file">Select File</label>
    <%= file_field 'upload', 'datafile' %></p>
    <%= submit_tag "Upload" %>
  <% end %>

  <% @images.each do |image| %>
     <%= image.id %><br/>
     <%= image.name %>
  <% end %>

Model

class DataFile < ActiveRecord::Base
    attr_accessor :upload

  def self.save_file(upload)   

    file_name = upload['datafile'].original_filename  if  (upload['datafile'] !='')    
    file = upload['datafile'].read    

    file_type = file_name.split('.').last
    new_name_file = Time.now.to_i
    name_folder = new_name_file
    new_file_name_with_type = "#{new_name_file}." + file_type

    image_root = "#{RAILS_CAR_IMAGES}"


    Dir.mkdir(image_root + "#{name_folder}");
      File.open(image_root + "#{name_folder}/" + new_file_name_with_type, "wb")  do |f|  
        f.write(file) 
      end

  end
end
like image 147
user1466717 Avatar answered Oct 04 '22 02:10

user1466717


The reason for the issue is encoding problems. It seems that you are reading the file in ASCII-8BIT mode and writing it in UTF-8 which means a conversion needs to take place. And conversion from ASCII-8BIT to UTF-8 isn't straight forward. Alternatively, you can specify binary mode for both reading and writing the files.

upload_file = File.new(<original file>, "rb").read

and

File.open(<final uploaded file>, "wb") {|f| f.write(upload_file) }
like image 23
Kashyap Avatar answered Oct 04 '22 02:10

Kashyap