2010-03-26 5 views
37

J'aimerais pouvoir lire un fichier XML téléchargé par l'utilisateur (moins de 100 Ko), mais ne pas avoir à sauvegarder ce fichier dans la base de données . Je n'ai pas besoin de ce fichier après l'action en cours (son contenu est analysé et ajouté à la base de données, mais l'analyse du fichier n'est pas le problème). Étant donné que les fichiers locaux peuvent être lus avec:comment lire un fichier téléchargé par l'utilisateur, sans l'enregistrer dans la base de données

File.read("export.opml") 

Je pensais simplement créer un file_field pour: uploaded_file, puis essayer de le lire avec

File.read(params[:uploaded_file]) 

mais tout ce qui ne fait jeter un TypeError (peut » t convertir HashWithIndifferentAccess en String). J'ai vraiment essayé beaucoup de choses différentes (y compris la lecture du répertoire/tmp), mais je n'ai pu obtenir aucune d'entre elles pour fonctionner. J'espère que la brièveté de ma question ne masque pas l'effort que j'ai donné pour essayer de résoudre ce problème par moi-même, mais je ne voulais pas polluer cette question de cent façons de ne pas l'obtenir. terminé. . Un grand merci à tous ceux qui carillons

Voici mon avis:

<% form_for(:uploaded_file, @feed, :url => {:action=>'parse'}, :html=> {:multipart=>true}) do |f| %> <p> 
    <%= f.label :uploaded_file, 'Upload your file.' %><br /> 
    <%= f.file_field :uploaded_file %> 
    </p> 
    <p><%= f.submit 'upload' %></p> 
<% end %> 

Je mis en place une action personnalisée (upload) qui gère le chargement file_field, qui, après la soumission, est passé à un autre action personnalisée (analyser) pour le traitement. Cela pourrait-il faire partie de mon problème?

Répondre

43

Vous êtes très proche. Vérifiez le class type de params[:uploaded_file], il devrait normalement être soit un StringIO ou un objet Tempfile - tous les deux agissant déjà comme des fichiers, et peuvent être lus en utilisant leurs méthodes respectives read.

Juste pour être sûr (le type de classe de params[:uploaded_file] peut varier selon que vous utilisez Mongrel, Passager, Webrick etc.) vous pouvez faire une tentative un peu plus exhaustive:

# Note: use form validation to ensure that 
# params[:uploaded_file] is not null 

file_data = params[:uploaded_file] 
if file_data.respond_to?(:read) 
    xml_contents = file_data.read 
elsif file_data.respond_to?(:path) 
    xml_contents = File.read(file_data.path) 
else 
    logger.error "Bad file_data: #{file_data.class.name}: #{file_data.inspect}" 
end 

Si, dans votre params[:uploaded_file] est un hachage, assurez-vous que vous n'avez pas confondu les paramètres object_name et method lorsque vous appelez file_field à votre avis, ou que votre serveur ne vous donne pas un hachage avec des clés comme :content_type etc. (dans lequel cas s'il vous plaît commenter sur ce poste avec le Bad file_data ... sortie de development.log/production.log.)

+0

Salut Vlad! Merci pour votre réponse. Je ne savais pas exactement comment utiliser votre code. Quand j'analyse, j'appelle file_data ou xml_contents d'une manière ou d'une autre. Comme si j'étais juste en train de définir xml = Fichier.lire (params [: upfile]) je parse (xml) Donc, je ne savais pas, mais pas un à arrêter là, j'ai essayé quelques choses différentes. J'ai essayé d'utiliser Webrick et Thin pour voir si les résultats étaient les mêmes ... ils l'étaient. Lors de l'utilisation de File.read (params [: upfile]), j'obtiens un "impossible de convertir HashWithIndifferentAccess en String" Est-ce que ça pourrait être le début de l'upfile? "uploaded_file" => {"uploaded_file" => # GoodGets

+0

Lorsque j'essaie d'utiliser le chemin xml = File.read (params [: upfile] .path) Je reçois un indéfini méthode 'path' Y a-t-il un problème avec ma "vue"? J'ai modifié ma question ci-dessus pour l'inclure. – GoodGets

+0

J'ai joué avec ma vue. J'utilise maintenant: <% form_for: flux,: url => {: controller => 'flux',: action => 'parse'} do | f | %> et quand je soumets maintenant le fichier téléchargé, je reçois un TypeError "ne peut pas convertir nil en String" Donc, je suppose que quelque chose ne se passe pas correctement. – GoodGets

6

J'ai besoin de lire les fichiers yaml. J'utilise remotipart et ici le code:

dans html.slim

=form_tag('/locations/check_for_import', method: :post, remote: true, multipart: true) 

...

<input id="uploadInput" type="file" name="uploadInput"> 

dans le contrôleur

content = File.read(params[:uploadInput].tempfile) 
doc = YAML.load(content) 
Questions connexes