Depuis que je me suis mis au Ruby on Rails, et donc initié au modèle MVC, j'ai toujours été stupéfait de voir un grand nombre de développeurs "gérer" les fichiers externes, envoyés par les internautes, dans leur controller ou leur model.

La logique même de séparation concepts différents aurait dû, selon moi, les inciter à créer des "medias manager", ou sortes de classes/modules pour gérer ces fichiers externes, de leur naissance à leur destruction.

N'ayant pas trouvé ce que je cherchais, j'ai créé il y a quelques mois un couple FileHandler/ImageHandler que j'ai étendu par la suite pour gérer les sons et vidéos. N'ayant depuis jamais encore trouvé de meilleure solution, j'aimerais bien savoir ce que vous en pensez. Voici donc une courte présentation de tout cela :
media manager rails
Et voici un exemple d'utilisation concret, une fois que les fichiers ont bien été 'required' comme il se doit :
in the view (app/views/photos/new.rhtml) :

<% form_for(:photo, :url => photos_path, :html => {:multipart => true}) do |f| %>
  <%= error_messages_for(:photo) %>
  <%=mff 'Sélectionnez le fichier à envoyer', file_field_tag(:file) %>
  <%=mff 'Description (facultatif)', f.text_area(:description) %>
  <p class="submit"><%= submit_tag('Envoyer cette photo »»') %></p>
<% end %>

in the controller (app/controllers/photos_controller.rb) :

class PhotosController < ApplicationController
#[...]
  def create
    @photo = Photo.create(params[:photo])
    @photo.store(params[:file])
    if @photo.save
      flash[:notice] = "Nouvelle photo enregistrée."
      redirect_to :action => 'new'
    else
      @photo.destroy
      render :action => 'new'
    end
  end
#[...]
end

in the model (app/models/photo.rb) :

 class Photo < ActiveRecord::Base
   before_destroy { |record| ImageHandler.delete_with_thumbnails(record.file_name) }

   def store(iostream)
     image = ImageHandler.new(iostream)
     begin
       image.store(self.id) # son nom de fichier sera son id + extension
     rescue
       @erreurs = $!.to_s # si une exception remonte l'ImageHandler ou du FileHandler, on l'ajoute à la liste d'erreurs de validations ActiveRecord
     else
       image.make_thumbnails 100, 150, 200, 250, 300 # chaque nombre représente le width d'un thumbnail de l'image qui sera fait
       update_attribute :file_name, image.raw_name # on rentre son nom dans la bdd
     end
   end

  protected
   def validate
     errors.add_to_base(@erreurs) if defined?(@erreurs) # l'ajout à la base se fait ici en réalité
   end
 end