Подтвердить что ты не робот

Как читать загруженный пользователем файл, не сохраняя его в базе данных

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

File.read("export.opml")

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

File.read(params[:uploaded_file])

но все, что делает, это throw 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 %>

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

4b9b3361

Ответ 1

Вы очень близки. Проверьте тип класса 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.)

Ответ 2

Мне нужно прочитать файлы 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)