Je suis très nouveau dans Ruby on Rails. Je suis coincé avec un problème. Je veux créer une fonctionnalité de téléchargement de fichier à travers laquelle je peux télécharger tout type de fichier (texte, image, etc.) Mon fichier de contrôleur est (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
Mon fichier modèle est (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
Mon fichier de vue est (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 %>
Maintenant, lorsque j'essaie de télécharger l'image, j'obtiens l'erreur "mode d'accès invalide wp" dans le fichier modèle. Lorsque je change File.open (chemin, "wp") en File.open (chemin, "w") dans le fichier modèle, cela donne l'erreur "'\ x89' de ASCII-8BIT à UTF-8". Pour le fichier .txt, cela fonctionne bien. J'utilise Ruby 1.9.3 et Rails 3.2.6
Merci par exemple, j'étudie Rails aussi!
Il fonctionne en Rails 3.1
Mon code:
Routes
resources :images do
collection { post :upload_image }
end
Manette
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
Voir 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 %>
Modèle
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
Le problème est dû à des problèmes d'encodage. Il semble que vous lisez le fichier en mode ASCII-8BIT et que vous l'écrivez en UTF-8, ce qui signifie qu'une conversion doit avoir lieu. Et la conversion de ASCII-8BIT en UTF-8 n'est pas simple. Alternativement, vous pouvez spécifier le mode binaire pour la lecture et l'écriture des fichiers.
upload_file = File.new(<original file>, "rb").read
et
File.open(<final uploaded file>, "wb") {|f| f.write(upload_file) }
Une autre excellente option serait carrierwave , qui est très simple à installer et le guide sur github peut vous permettre d'être opérationnel en quelques minutes. Ajoutez-le à votre gemfile puis exécutez bundle install
Il y a aussi un bon railscast sur le sujet
utilisez "wb" au lieu de "wp". Ça marche
File.open(path, "wb") { |f| f.write(upload['datafile'].read)}