15 votes

Support des flux binaires de Rails

Je vais bientôt lancer un projet qui nécessite la prise en charge de fichiers binaires assez volumineux. J'aimerais utiliser Ruby on Rails pour la webapp, mais je suis préoccupé par le support des BLOB. D'après mon expérience avec d'autres langages, frameworks et bases de données, les BLOB sont souvent négligés et ont donc des fonctionnalités médiocres, difficiles et/ou boguées.

Le RoR prend-il en charge les BLOB de manière adéquate ? Y a-t-il des problèmes qui surgissent une fois que l'on est déjà engagé dans Rails ?

BTW : Je souhaite utiliser PostgreSQL et/ou MySQL comme base de données dorsale. Évidemment, le support des BLOB dans la base de données sous-jacente est important. Pour le moment, je veux éviter de me concentrer sur les capacités BLOB de la base de données ; je suis plus intéressé par la réaction de Rails lui-même. Idéalement, Rails devrait me cacher les détails de la base de données, et je devrais donc pouvoir passer de l'une à l'autre. Si c'est le cas pas (c'est-à-dire qu'il y a un problème avec l'utilisation de Rails avec une base de données particulière), veuillez le mentionner.

MISE À JOUR : Je ne parle pas seulement d'ActiveRecord ici. J'aurai besoin de gérer les fichiers binaires du côté HTTP (téléchargement de fichiers de manière efficace). Cela signifie avoir accès aux en-têtes HTTP et aux flux appropriés via Rails. J'ai mis à jour le titre et la description de la question pour refléter cela.

13voto

Jim Puls Points 29289

Pour ce qui est de la diffusion en continu, vous pouvez tout faire de manière efficace (du moins en termes de mémoire). Du côté du téléchargement, les paramètres de fichier dans les formulaires sont abstraits en tant qu'objets IO que vous pouvez lire ; du côté du téléchargement, regardez dans la forme de render :text => qui prend un argument Proc :

render :content_type => 'application/octet-stream', :text => Proc.new {
    |response, output|
    # do something that reads data and writes it to output
}

En revanche, si vos données se trouvent dans des fichiers sur disque, les solutions susmentionnées seront certainement plus efficaces.

8voto

Matt Rogish Points 11824

+1 pour attachment_fu

J'utilise attachment_fu dans une de mes applications et je DOIS stocker les fichiers dans la base de données (pour des raisons ennuyeuses qui sortent du cadre de cette conversation).

La (seule ?) difficulté que j'ai rencontrée avec les BLOB est que vous avez besoin d'un chemin de code séparé pour envoyer les données à l'utilisateur - vous ne pouvez pas simplement mettre en ligne un chemin sur le système de fichiers comme vous le feriez s'il s'agissait d'un simple fichier.

Par exemple, si vous stockez des informations sur les avatars, vous ne pouvez pas simplement faire :

<%= image_tag @youruser.avatar.path %>

vous devez écrire une logique d'encapsulation et utiliser send_data, par exemple (l'exemple ci-dessous est UNIQUEMENT un exemple avec w/attachment_fu, dans la pratique, vous devrez le DRY)

send_data(@youruser.avatar.current_data, :type => @youruser.avatar.content_type, :filename => @youruser.avatar.filename, :disposition => 'inline' )

Malheureusement, pour autant que je sache, attachment_fu (je n'ai pas la dernière version) ne fait pas d'habillage intelligent pour vous - vous devez l'écrire vous-même.

P.S. J'ai vu votre question éditer - Attachment_fu gère toutes les choses ennuyeuses que vous mentionnez -- à propos de la nécessité de connaître les chemins de fichiers et toutes ces conneries -- SAUF le petit problème lors du stockage dans la BD. Essayez-le ; c'est le standard pour les applications Rails. Si vous insistez pour réinventer la roue, le code source de attachment_fu devrait également documenter la plupart des problèmes !

5voto

John Topley Points 58789

Vous pouvez utiliser le :binary dans votre migration ActiveRecord et contraindre également la taille maximale :

class BlobTest < ActiveRecord::Migration
  def self.up
    create_table :files do |t|
      t.column :file_data, :binary, :limit => 1.megabyte
    end
  end
end

ActiveRecord expose le contenu du BLOB (ou CLOB) comme une chaîne Ruby.

3voto

Teflon Ted Points 2823

Je pense que votre meilleure chance est le plug-in attachment_fu : http://github.com/technoweenie/attachment_fu/tree/master

UPDATE : J'ai trouvé plus d'informations ici http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/a81beffb93708bb3

0voto

Regardez dans le plugin, x_send_file aussi.

"Le plugin XSendFile fournit une interface simple pour envoyer des fichiers via l'en-tête HTTP X-Sendfile. Cela permet à votre serveur web de servir le fichier directement à partir du disque, au lieu de le diffuser à travers votre processus Rails. C'est plus rapide et permet d'économiser beaucoup de mémoire si vous utilisez Mongrel. Tous les serveurs web ne prennent pas en charge cet en-tête. YMMV".

Je ne suis pas sûr qu'il soit utilisable avec les Blobs, peut-être seulement pour les fichiers du système de fichiers. Mais vous avez probablement besoin de quelque chose qui n'encombre pas le serveur web en diffusant de gros morceaux de données.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X