Questo tipo di problema è problematico dal punto di vista di Rails a causa del modo in cui funzionano i caricamenti di immagini. Una strategia per farlo funzionare meglio è:
- Fai un sotto-modulo per il caricamento delle immagini, possibilmente utilizzando swfupload per renderlo più snello.
- Creare un modello per ricevere i tuoi caricamenti che include una chiave di accesso casuale utilizzata per recuperarla e collegarla. Paperclip gestisce il file allegato.
- Utilizzare AJAX per compilare il modulo principale inserendo un campo nascosto o potenzialmente un elemento di casella di controllo visibile con il tasto unique appropriato, al termine della sottomaschera.
Un modello tipico simile a questa:
class Avatar < ActiveRecord::Base
has_attached_file :image
# ... Additional Paperclip options here
before_validation :assign_unique_key
belongs_to :user
def to_param
self.unique_key
end
protected
def assign_unique_key
return if (self.unique_key.present?)
self.unique_key = Digest::SHA1.hexdigest(ActiveSupport::SecureRandom.random_number(1<<512).to_s)
end
end
Il motivo per il campo unique_key è così che si può collegare questo per la forma di un disco potenzialmente non salvati. È vantaggioso utilizzare il tasto unique_key anziché id quando lo si inserisce negli URL, poiché è difficile stabilire se un utente debba essere in grado di vedere o meno questa immagine quando viene caricata poiché l'utente proprietario non può ancora essere assegnato.
Ciò impedisce anche alle persone curiose di alterare un tipo di ID sequenziale e facilmente ipotizzabile nel proprio URL e di vedere altri avatar che sono stati caricati.
È possibile recuperare l'ultimo URL ridimensionato dell'anteprima per l'Avatar come si farebbe con qualsiasi modello a questo punto.
Si può facilmente striscia fuori i parametri al ricevimento e tradurre di nuovo a numeri ID Avatar:
# If an avatar_id parameter has been assigned...
if (params[:user][:avatar_id])
# ...resolve this as if it were a unique_key value...
avatar = Avatar.find_by_unique_key(params[:user][:avatar_id])
# ...and repopulate the parameters if it has been found.
params[:user][:avatar_id] = (avatar && avatar.id)
end
# ... params[:user] used as required for create or update
Come persone caricare e ricaricare le immagini, vi troverete infine avere un gran numero di record orfani che non sono effettivamente usato ovunque È semplice scrivere un'attività di rake per eliminare tutto ciò dopo che è trascorso un ragionevole lasso di tempo. Ad esempio:
task :purge_orphan_avatars => :environment do
# Clear out any Avatar records that have not been assigned to a particular
# user within the span of two days.
Avatar.destroy_all([ 'created_at<? AND user_id IS NULL', 2.days.ago ])
end
Uso destroy_all dovrebbero avere l'effetto di spurgo tutto il materiale graffetta pure.