Upload de fichiers dans un champs de type BLOB d'une base Oracle



Ecrit par Anthony Heukmes le 31 mars 2009 10:49

0 commentaire



Les clients habitués aux mondes J2EE et Oracle sont souvent réticents à l'idée de passer à Ruby on Rails. Ils veulent avant tout s'assurer que ce nouvel outil permettra de réaliser au moins autant que l'ancien. Et c'est tout à fait normal.
Pour se faire, ils demandent régulièrement qu'une POC (Proof of Concept) soit développée afin de confirmer qu'une fonctionnalité donnée peut facilement être implémentée en Rails.

Lors d'une de mes dernières réunions, j'ai eu droit à la réflexion suivante : "Tu es sûr qu'il n'y aura pas de problèmes pour uploader des fichiers dans la base Oracle? J'avais moi aussi essayé un langage de script (PHP) et j'avais rencontré de nombreux problèmes".

Voici donc ma POC permettant de répondre à cette question.
J'ai spécifié Oracle dans le titre de cet article mais le code que vous allez découvrir n'a rien de spécifique à ce SGBD.

Nous avons tout d'abord besoin d'une table et d'un modèle pour stocker les données associées à notre fichier. Vous aurez également besoin d'un contrôleur et de différentes views.
Vous pouvez donc pour cela utiliser le script de génération fournit par Rails (scaffold) :


$ ./script/generate scaffold FileUpload name:string content_type:string content_size:integer content:binary


Voici mon fichier de migration :

class CreateFileUploads < ActiveRecord::Migration

def self.up
create_table :file_uploads do |t|
t.string :name
t.string :content_type
t.integer :content_size
t.binary :content
t.timestamps
end
end

def self.down
drop_table :file_uploads
end
end



Remarquez le type de la colonne "content" qui est binary. Cela générera un BLOB dans votre base de données lorsque vous effectuerez la migration :

$ rake db:migrate


Rien de particulier concernant le modèle :

class FileUpload < ActiveRecord::Base

end


Modifiez ensuite le formulaire de création (new.html.erb) afin qu'il ressemble à ceci :


<% form_for @file_upload, :html => { :multipart => true } do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :content %><br />
<%= f.file_field :content %>
</p>
<p>
<%= f.submit 'Create' %>
</p>
<% end %>



Le formulaire a été défini comme étant multipart et le champ content est maintenant de type file_field.

Vous pouvez alors travailler sur la méthode create de votre contrôleur :

def create

@file_upload = FileUpload.new(params[:file_upload])
if @file_upload.valid?
@file_upload.name = params[:file_upload][:content].original_filename
@file_upload.content = params[:file_upload][:content].read
@file_upload.content_type = params[:file_upload][:content].content_type
@file_upload.content_size = params[:file_upload][:content].size
@file_upload.save
flash[:notice] = 'FileUpload was successfully created.'
redirect_to @file_upload
else
render :action => "new"
end
end


Rien de très compliqué, le paramètre params[:file_upload][:content] contient un objet de type ActionController::UploadedStringIO sur lequel vous pouvez effectuer différentes opérations telles que la lecture des données, la récupération du type de contenu, la taille, ... Toutes ces informations sont ensuite sauvées dans la base de données.

Dans la page show.html.erb, remplacez l'affichage du contenu par un lien de téléchargement :


<p>
<b>Content:</b>
<%= link_to "Download", :action => "download", :id => @file_upload.id %>
</p>


Créez enfin cette méthode download dans votre contrôleur :

def download

file = FileUpload.find(params[:id])
if file
send_data(file.content, :type => file.content_type , :filename => file.name)
else
flash[:error] = "Invalid file ID!"
redirect_to :action => "index"
end
end



Une fois de plus, c'est très simple. L'enregistrement de type FileUpload est récupéré dans la base de données grâce à son ID. Le fichier associé est alors retourné par l'intermédiaire de la méthode send_data.

Vous pouvez maintenant sauvegarder n'importe quel type de fichier dans votre base de données Oracle!
Bookmark and Share

Ajouter un commentaire



0 commentaire pour cet article