Benito Serna Tips and tools for Ruby on Rails developers

Add many attachments without deleting previous ones using ActiveStorage

May 16, 2023

If you want to add many attachments to a record using just a file field, but you don’t want to remove the previous images from the record on every update, like in the following code:

<%= form_with(model: product) do |form| %>
    <%= form.label :images %>
    <%= form.file_field :images, multiple: true %>
  <%= form.submit %>
<% end %>

And instead, on every update you want to add the new images to the record, here is a simple workaround…

A virtual new_images attribute

Instead of using the :images attribute, you can add a virtual :new_images attribute, using an attr_reader and a custom writer like this:

class Product < ApplicationRecord
  attr_reader :new_images

  has_many_attached :images

  def new_images=(images)
    self.images.attach(images)
  end
end

And use that attribute in your file_field:

<%= form_with(model: product) do |form| %>
    <%= form.label :new_images %>
    <%= form.file_field :new_images, multiple: true %>
  <%= form.submit %>
<% end %>

Also, update your “params method” in the controller:

def create
  @product = @site.products.new(product_params)
  #...
end

def update
  @product.update(product_params)
  # ...
end

private

def product_params
  params.require(:product).permit(new_images: [])
end

This way, when you assign new images, your record will attach the received images instead of updating the images field with the new images.

Related articles

Weekly tips and tools for Ruby on Rails developers

I send an email each week, trying to share knowledge and fixes to common problems and struggles for ruby on rails developers, like How to fetch the latest-N-of-each record or How to test that an specific mail was sent or a Capybara cheatsheet. You can see more examples on Most recent posts or All post by topic.