To może być trochę za późno na PO, ale mam nadzieję, że ktoś pomaga. Musiałem zapisać przesłany obraz w sesji użytkownika (ponownie dla formularza wieloetapowego), a ja też zacząłem od Ryana Railscast #217, ale aplikacja szybko wykroczyła poza to. Zauważ, że moje środowisko było Rails 4 na Ruby 2, używając Carrierwave i MiniMagick, a także activerecord-session_store, które wyjaśnię poniżej.
Uważam, że problemem, z którym miałem do czynienia zarówno z OP, jak i ze mną, było to, że próbowaliśmy dodać wszystkie parametry POST do sesji użytkownika, ale przy przesyłaniu pliku, jednym z parametrów był rzeczywisty obiekt UploadedFile, który jest sposobem na to duże. Podejście opisane poniżej jest kolejnym rozwiązaniem tego problemu.
Zastrzeżenie: Jak powszechnie wiadomo, nie jest idealne przechowywanie złożonych obiektów w sesji użytkownika, lepiej przechowywać identyfikatory rekordów lub inne dane identyfikatora (np. Ścieżkę obrazu) i wyszukiwać te dane, gdy jest to potrzebne. Dwa główne powody, dla których synchronizacja sesji i modelu/danych bazy danych jest zsynchronizowana (zadanie nietrywialne), a domyślny magazyn sesji Rails (z wykorzystaniem plików cookie) jest ograniczony do 4 kb.
mojego modelu (submission.rb):
class Submission < ActiveRecord::Base
mount_uploader :image_original, ImageUploader
# ...
end
Controller (submissions_controller.rb):
def create
# If the submission POST contains an image, set it as an instance variable,
# because we're going to remove it from the params
if params[:submission] && params[:submission][:image_original] && !params[:submission][:image_original].is_a?(String)
# Store the UploadedFile object as an instance variable
@image = params[:submission][:image_original]
# Remove the uploaded object from the submission POST params, since we
# don't want to merge the whole object into the user's session
params[:submission].delete(:image_original)
end
# Merge existing session with POST params
session[:submission_params].deep_merge!(params[:submission]) if params[:submission]
# Instantiate model from newly merged session/params
@submission = Submission.new(session[:submission_params])
# Increment the current step in the session form
@submission.current_step = session[:submission_step]
# ... other steps in the form
# After deep_merge, bring back the image
if @image
# This adds the image back to the Carrierwave mounted uploader (which
# re-runs any processing/versions specified in the uploader class):
@submission.image_original = @image
# The mounted uploader now has the image stored in the Carrierwave cache,
# and provides us with the cache identifier, which is what we will save
# in our session:
session[:submission_params][:image_original] = @submission.image_original_cache
session[:image_processed_cached] = @submission.image_original.url(:image_processed)
end
# ... other steps in the form
# If we're on the last step of the form, fetch the image and save the model
if @submission.last_step?
# Re-populate the Carrierwave uploader's cache with the cache identifier
# saved in the session
@submission.image_original_cache = session[:submission_params][:image_original]
# Save the model
@submission.save
# ... render/redirect_to ...
end
end
Mój plik uploader był głównie zapasy z pewnym przetwarzania niestandardowej.
Uwaga: aby rozbudować sesji, używam ActiveRecord-session_store, który jest klejnotem, który był ekstrahowany z rdzenia Rails w V4, który dostarcza sklep sesji bazy danych oparciem (zwiększając limit sesji 4KB). Postępuj zgodnie z the documentation, aby uzyskać instrukcje instalacji, ale w moim przypadku było to dość szybkie i bezbolesne, aby ustawić i zapomnieć. Uwaga dla użytkowników o dużym natężeniu ruchu: pozostałe rekordy sesji nie wydają się być usuwane przez klejnot, więc jeśli uzyskasz wystarczający ruch, ta tabela może potencjalnie zostać wypełniona niezliczoną liczbą wierszy.
czy faktycznie przesyłasz plik obrazu lub plik ze słowami Microsoft Word? –
Muszę sprawdzić typ pliku przed przesłaniem go. – AlphaB
Powinieneś złapać 'CarrierWave :: IntegrityError' lub użyć metody' store() '(bez!), Aby nie wyświetlać błędu. –