Rails Delayed Job, agregar carga de imágenes a la tarea de Delayed Job.
Tengo una aplicación de Rails simple que carga fotos a un objeto con ActiveStorage.
class ProjectAsset < ApplicationRecord
belongs<em>to :project
belongs</em>to :user
<p>has<em>one</em>attached :asset </p>
<p>has<em>many :comments, dependent: :delete</em>all
accepts<em>nested</em>attributes_for :comments</p>
<p>#DB columns => :project<em>id :asset :user</em>id
end
```</p>
Y los almacena en AWS S3:
</code></pre>
test:
service: Disk
root: <%= Rails.root.join("tmp/storage") %>
local:
service: Disk
root: <%= Rails.root.join("storage") %>
amazon:
service: S3
access<em>key</em>id: <strong>*
secret<em>access</em>key: <em></em></strong>
region: <strong>
bucket: *</strong>
```
Tengo un formulario simple:
```
<%= form<em>for ProjectAsset.new do |form| %>
<%= form.hidden</em>field :project<em>id, :value => @project.id %>
<%= form.hidden</em>field :user<em>id, :value => current</em>user.id %>
<%= form.file<em>field :asset, multiple: false, direct</em>upload: true, class: "", onchange: "autoUpload(this);" %>
<%= form.submit 'Añadir esta Foto' %>
<% end %>
<pre><code><br />Esto guarda la imagen y redirige automáticamente a la plantilla de vista correspondiente.
</code></pre>
def create
@project<em>asset = ProjectAsset.new(project</em>asset_params)
<pre><code>respond_to do |format|
if @project_asset.save
format.html { redirect_to project_path(@project_asset.project), notice: "El elemento del proyecto se creó correctamente." }
format.json { render :show, status: :created, location: @project_asset }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @project_asset.errors, status: :unprocessable_entity }
end
end
</code></pre>
end
```
Mi pregunta es la siguiente, y es un poco de dos partes.
1) ¿Cómo puedo poner solo la imagen (:asset) que se está cargando en la cola Delayed::Job en la acción :create
y que el resto del registro se guarde y continúe con la redirección?
y
2) Tengo la imagen mostrada en la plantilla de vista después de la redirección. Esto está bien si hay una transferencia de datos lo suficientemente rápida, pero es una pesadilla si estás fuera de wifi. ¿Cómo puedo usar la imagen local del usuario en el directorio storage
como la imagen hasta que se haya cargado completamente en S3?
davy.ai
after_commit
con la opciónon: :create
para asegurarte de que el trabajo solo se encole cuando se crea el registro, no cuando se actualiza. Aquí tienes un ejemplo:Esto encolará un trabajo con el
id
del registro que acaba de ser creado. Puedes crear una nueva clase de trabajo (ProjectAsset::AssetUploadJob
en este ejemplo) que maneje el procesamiento retrasado de la subida de la imagen.Para mostrar la imagen local del usuario en
storage
hasta que el recurso se haya subido completamente a S3, puedes usar el métodourl
del objetoActiveStorage::Attachment
para obtener una URL temporal para la imagen. Esta URL solo será válida por un corto período de tiempo (por defecto, 5 minutos), así que debes usarla con precaución.Aquí tienes un ejemplo de cómo puedes utilizar el método
url
en tu vista:Esto mostrará la imagen con un tamaño de 300×300 píxeles y una URL temporal que solo será válida durante 1 minuto. Puedes ajustar la opción
expires_in
para controlar cuánto tiempo es válida la URL.