user3574603
user3574603

Reputation: 3618

Rails 5 ActiveStorage: Why does my form forget the selected file when the page is re-rendered?

I am using active storage to implement file uploads in a form.

<%= form_for @listing do |form| %>
  # ...
  <%= form.text_field :title, placeholder: "Title" %>
  <%= form.file_field :image, direct_upload: true, accept: "image/png,image/gif,image/jpeg" %>
  # ...
<% end %>

I handle the form submission in the controller like so:

  def create
    @listing = Listing.new(safe_params)
    if @listing.save
      flash[:success] = "Your posting has been submitted"
      redirect_to root_url
    else
      flash.now[:warning] = @listing.errors.full_messages
      render 'new'
    end
  end

If validations fail, the new page is re-rendered. If I've already entered a title, the previously entered title is present in the re-rendered form. However, if I've already selected a file, that file is not selected in the re-rendered form.

I select a file:

File is selected

On submission, the file is uploaded but validation fails and the page is re-rendered. The file is no longer selected:

File is no longer selected

I'm not quite sure what's going on here. Why isn't the file remembered when the new page is re-rendered? Why doesn't the form display the selected file? What do I need to do to ensure it's still selected when the page re-renders?

Upvotes: 0

Views: 1246

Answers (2)

Anand
Anand

Reputation: 6531

This is a common issue with browser you can think it as -

File field as a one-way field. Browser to server, but not server to browser.

That's not how a file field works in any browser.

So on edit page you would have to explicitly preview file or file name at any other place just to let user know that there is already a file present unless he want to update that with another file.

<%= form_for @listing do |form| %>
   #...
    <div>
      <%if form.object.image.present?%>
        #name of file
      <%end%>
    </div>
    <%= form.file_field :image, direct_upload: true, accept: "image/png,image/gif,image/jpeg" %>
    #..
<%end%>

Upvotes: 0

gabrielhilal
gabrielhilal

Reputation: 10769

You could try something like this:

<%= form_for @listing do |form| %>
  # ...
  <%= form.text_field :title, placeholder: "Title" %>
  <%= form.hidden_field :image, value: form.object.image.signed_id if form.object.image.attached? %>
  <%= form.file_field :image, direct_upload: true, accept: "image/png,image/gif,image/jpeg" %>
  # ...
<% end %>

Upvotes: 1

Related Questions