как прочитать загруженный пользователем файл, не сохраняя его в базе данных - PullRequest
40 голосов
/ 26 марта 2010

Я хотел бы иметь возможность читать XML-файл, загруженный пользователем (менее 100 КБ), но мне не нужно сначала сохранять этот файл в базе данных. Мне не нужен этот файл после текущего действия (его содержимое анализируется и добавляется в базу данных; однако анализ файла не является проблемой). Поскольку локальные файлы можно прочитать с помощью:

File.read("export.opml")

Я думал о том, чтобы просто создать file_field для: uploaded_file, а затем попытаться прочитать его с помощью

File.read(params[:uploaded_file])

, но все, что он делает, это генерирует ошибку TypeError (не может преобразовать HashWithIndifferentAccess в String). Я действительно пробовал много разных вещей (включая чтение из каталога / tmp), но не смог заставить ни одну из них работать.

Я надеюсь, что краткость моего вопроса не скроет усилия, которые я приложил, чтобы попытаться решить это самостоятельно, но я не хотел загрязнять этот вопрос сотнями способов, как НЕ сделать этого , Большое спасибо всем, кто вмешивается.

Вот мой взгляд:

<% 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 %>

Я настроил настраиваемое действие (загрузка), которое обрабатывает загрузку file_field, которая после отправки передается другому настраиваемому действию (анализ) для обработки. Может ли это быть частью моей проблемы?

Ответы [ 2 ]

46 голосов
/ 26 марта 2010

Вы очень близки. Проверьте тип класса из params[:uploaded_file], обычно это должен быть либо StringIO, либо Tempfile объект - оба из которых уже действуют как файлы, и могут быть прочитаны с использованием их соответствующих read методов.

Просто чтобы быть уверенным (тип класса params[:uploaded_file] может варьироваться в зависимости от того, используете ли вы Mongrel, Passenger, Webrick и т. Д.), Вы можете сделать чуть более исчерпывающую попытку:

# 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

Если в вашем случае окажется, что params[:uploaded_file] - это хеш, убедитесь, что вы не ошибочно перевернули параметры object_name и method при вызове file_field в вашем или ваш сервер не дает вам хэш с ключами типа :content_type и т. д. (в этом случае, пожалуйста, прокомментируйте этот пост с выводом Bad file_data ... из development.log / production.log.)

7 голосов
/ 20 февраля 2015

Мне нужно прочитать файлы yaml. Я использую remotipart и здесь код:

в html.slim

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

...

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

в контроллере

content = File.read(params[:uploadInput].tempfile)
doc = YAML.load(content)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...