Jak radzić sobie z przesyłaniem plików w kolejce bez dołączania ich do aktywnego rekordu?
Chcę tylko zapisać pliki na dysku.przesyłanie plików bez aktywnego rekordu
Dzięki,
Jak radzić sobie z przesyłaniem plików w kolejce bez dołączania ich do aktywnego rekordu?
Chcę tylko zapisać pliki na dysku.przesyłanie plików bez aktywnego rekordu
Dzięki,
Jeśli dobrze rozumiem, co trzeba wtedy najprostszym przykładem może być to:
Kontroler:
class UploadController < ApplicationController
def new
end
def create
name = params[:upload][:file].original_filename
path = File.join("public", "images", "upload", name)
File.open(path, "wb") { |f| f.write(params[:upload][:file].read) }
flash[:notice] = "File uploaded"
redirect_to "/upload/new"
end
end
Widok:
<% flash.each do |key, msg| %>
<%= content_tag :div, msg, :class => [key, " message"], :id => "notice_#{key}" %>
<% end %>
<% form_tag '/upload/create', { :multipart => true } do %>
<p>
<%= file_field_tag 'upload[file]' %>
</p>
<p>
<%= submit_tag "Upload" %>
</p>
<% end %>
byłoby to pozwalają przesłać dowolny plik bez żadnych sprawdzeń lub zatwierdzeń, które moim zdaniem nie są aż tak użyteczne.
Jeśli sam bym to zrobił, użyłbym czegoś takiego jak validatable gem lub tableless gem tylko tableless nie jest już obsługiwany. Te klejnoty pozwolą Ci zweryfikować to, co przesyłasz, aby było bardziej rozsądne.
Upewnij się, że używasz <% = form_tag ...%> w szynach 3. – cider
aby zachować spójność nie powinieneś używać 'File.join (" public "," images "," upload ")' do tworzenia 'katalogu '? – Crashalot
Pewnie, to dobra wskazówka. Napisałem to naprawdę dawno temu :) Nie sądzę, żebym wiedział jak to zrobić w tym czasie :) Użyłem tylko przykładów przy kodowaniu więc w jednym wierszu go używam :)) Z drugiej strony nie. Aktualizuję teraz. –
Można spróbować użyć Rails plugin Attachment_fu do obsługi przesłanych plików. Umożliwia zapisywanie ładowanych plików do systemu plików zamiast do bazy danych.
attachement_fu need activerecord .... – Mike
Dokumentacja Tempfile
pokazuje przykład, który jest równoważny z kodem Rytis, który jest w porządku przez większość czasu. Ale gdy zadzwonisz pod numer tempfile.read
, Ruby odczytuje cały plik jako pojedynczą porcję do pamięci, która jest nieoptymalna.
Jednak FileUtils
dostarcza sposobu copy_stream
i IO
, przynajmniej w Ruby 2.0, zapewnia copy_stream
realizację który obsługuje pisanie bezpośrednio do filePath (FileUtils.copy_stream
wymaga plikopodobny obiektów po obu stronach, a przynajmniej tak mówią dokumenty).
W moim przypadku zainicjowałem duże wysyłanie wielu plików przez AJAX i chciałem uniknąć czytania całego pliku (ów) w pamięci Ruby przed zapisaniem na dysk.
W poniższym przykładzie params[:files]
jest Array
od ActionDispatch::Http::UploadedFile
przypadkach i local_filepath
jest ciągiem wskazując na nie istniejący plik w istniejącym katalogu. Dla zwięzłości, będę zakładać, mam tylko przesłać jeden plik:
IO.copy_stream(params[:files][0].tempfile, local_filepath)
Instancja ActionDispatch::Http::UploadedFile
ma .tempfile
pole, które jest po prostu regularne Tempfile
instancji.
Nie jestem pewien, czy Ruby wciąż nie czyta całego pliku w pamięci - nie testowałem niczego, ale jest to dużo bardziej możliwe niż w przypadku składni localfile.write(tempfile.read)
.
tl; dr: IO.copy_stream(your_tempfile, your_disk_filepath)
jest bardziej zwięzły, jeśli nie szybszy.
można po prostu przenieść plik tymczasowy do ścieżki przeznaczenia przy użyciu fileutils
tmp = params[:my_file_field].tempfile
destiny_file = File.join('public', 'uploads', params[:my_file_field].original_filename)
FileUtils.move tmp.path, destiny_file
Spróbuj http://easyrails.herokuapp.com/blogs/5/upload-file-in-rails-without-model- tworzenie – vajapravin