ruby-on-railsrails-activestorageruby-on-rails-6

What is the correct way to update images with has_many_attached in Rails 6


I have a Rails 6 app that uses Active Storage to store multiple images to a model (Activity) with has_many_attached.

I don't understand how to append extra images instead of replacing the existing images. When I upload images the first time they save correctly. However, when I update the record, and I add a new image, the previous images are replaced by the new image. In Rails 5 the new image would be appended without replacing the previously saved images.

How do I append a new image instead of replacing the previous images?

I have an Activity model that has the following:

has_many_attached :images

In the form I have:

<%= f.file_field :images, multiple: true %>

In the controller I have the following:

def update
  @activity = Activity.find(params[:id])

  if @activity.update(activity_params)
    flash[:success] = "Saved"
    redirect_to activity_path(@activity)
  else
    flash[:error] = "Not saved"
    redirect_to edit_activity_path(@activity)
  end
end

private

  def activity_params
    params.require(:activity).permit(:name, images:[])
  end

Solution

  • This is the solution that I have now:

    Add this to the update action:

    if params[:activity][:images].present?
      params[:activity][:images].each do |image|
      activity.images.attach(image)
    end
    

    So, the entire update action looks like this:

    def update
      if activity.update(activity_params)
        if params[:activity][:images].present?
          params[:activity][:images].each do |image|
            activity.images.attach(image)
          end
        end
        flash[:success] = 'Updated!'
        respond_with activity, location: activity_path(activity)
      else
        flash[:error] = 'Not updated'
        respond_with activity, location: activity_path(activity)
      end
    end
    

    And remove this from permitted params:

    images:[]