[RUBY] [Rails] How to solve the problem that the default image is overwritten when editing without uploading the image [Active Storage]

I've found a new bug while my personally-developed app is getting pretty close to completion ... (I'm glad I noticed it before it was released).

The introduction is long, so if you want to know the solution quickly, please skip this area! !!

I implemented the image upload function such as profile image using ActiveStorage, but the following bugs were found. For example, suppose a user sets an image on a user edit page. And then suppose you want to change your password. Naturally, the user only enters the new password and that value is posted from the form on the edit page. At this time, the previously uploaded image is not set in the file selection area (file_field) of the form, so if the update action is executed in this state, the previously uploaded image will disappear and it is set in the application. It will be overwritten with the default image.

In other words, it provides the user with the worst UX that they can't keep the image changes unless they upload the image every time they edit. This has to be done, so I'll write a solution!

Solution (super easy)

Add the following to the controller.

users_controller.rb


def update
    @user = User.find(params[:id])
    @user.avatar.attach(params[:avatar]) if @user.avatar.blank?
    if @user.update(user_params)
      flash[:success] = 'I updated my profile'
      redirect_to @user
    else
      render 'edit'
    end
  end

Just add ** if @ user.avatar.blank? **! Actually, I didn't know how to create a cache of images already set in ActiveStorage regardless of whether I googled or googled, so as a result of thinking for myself and verifying various hypotheses, I was able to come up with this sentence and solve it. I did. (It came out with CarrierWave) I confirmed that the test also passed. (It has been confirmed that the test will fail properly if this sentence is erased)

But with this

** If you want to change the already set image normally, `@ user.avatar.bkank?` becomes false and `@ user.avatar.attach (params [: avatar])` Isn't it possible to change the image without executing? ** **

Do not you think so? I think. .. Even with w, the actual image is updated and the test passes, so I'm going to use this for the time being.

** If anyone understands the principle around here, I would appreciate it if you could comment. ** **

Test code

As a supplement, the test code that actually passed is posted here (only the relevant part is excerpted).

upload_image_spec.rb


require 'rails_helper'

RSpec.describe 'Image upload', type: :system do
  let(:user) { FactoryBot.create(:user) }

  before do
    valid_login(user)
  end

  #Upload and save images
  def upload_user_avatar(user)
    visit edit_user_path(user)
    attach_file 'user_avatar', "#{Rails.root}/spec/fixtures/images/test.jpg "
    click_on 'save'
  end

  it 'Images uploaded by user should be displayed on My Page' do
    upload_user_avatar(user)
    expect(page).to have_selector("img[src$='test.jpg']")
  end

  it "The user succeeds in updating the image" do
    visit edit_user_path(user)
    attach_file 'user_avatar', "#{Rails.root}/spec/fixtures/images/updated_test.jpg "
    click_on 'save'
    expect(page).to have_selector("img[src$='updated_test.jpg']")
  end

  it "When editing without uploading the image, it should not be overwritten with the default image data" do
    upload_user_avatar(user)
    visit edit_user_path(user)
    click_on 'save'
    expect(page).to have_selector("img[src$='test.jpg']")
  end
end

Thank you for reading to the end!

I output what I learned every day! If you have any suggestions, I would be grateful if you could comment! !!

Recommended Posts

[Rails] How to solve the problem that the default image is overwritten when editing without uploading the image [Active Storage]
How to solve the problem that the website image is not displayed after deploying to heroku on Rails 5
How to solve the problem when the value is not sent when the form is disabled in rails and sent
How to solve the problem that it is not processed normally when nesting beans in Spring Batch
How to fix the problem that the upper half is cut off when using UITabBar
[Rails] How to use Active Storage
How to write the view when Vue is introduced in Rails?
How to solve the problem that you can not pull image from docker hub with Minikube
Incident (rails) that is logged out when user editing of the application
How to solve the problem that notification cannot be requested on iOS14
How to implement image posting function using Active Storage in Ruby on Rails
I want to solve the problem that JS is not displayed properly unless reloaded when transitioning with Turbolinks: link_to
[Rails] How to solve the error "undefined method` visit'" when using Capybara with Rspec
[Rails] How to display an image in the view
How to solve the problem that line breaks in cells are amplified when outputting EXCEL using SXSSF Workbook (3.16 or older)
[Ruby on Rails] I want to get the URL of the image saved in Active Storage
When is the default value automatically entered without explicit initialization?
[Rails] How to convert the URI of the image sent by http to https when using Twitter API
[Rails carrier wave] How to not transition to the error screen even if the image upload is not selected
Problem investigation that JST is converted to +0000 +0000 when golang timezone conversion is performed on Alpine docker image
About the solution to the problem that the log of logback is not output when the web application is stopped
[Rails] How to solve ActiveSupport :: MessageVerifier :: InvalidSignature that I was addicted to when introducing twitter login [ActiveStorage]
Lenovo ThinkPad T14 Gen1 How to solve the problem that the speaker becomes dummy and cannot be used when installing Ubuntu 20.04 on AMD
How to output the value when there is an array in the array
I tried to understand how the rails method "redirect_to" is defined
I tried to understand how the rails method "link_to" is defined
How to identify the path that is easy to make a mistake
How to solve the unknown error when using slf4j in Java
[Rails 5] How to display the password change screen when using devise
[rails6.0.0] How to save images using Active Storage in wizard format
[IOS] What to do when the image is filled with one color
[Note] How to expand storage when Sakura's VPS is scaled up (CentOS 7)
[Rails] About the error that the image is not displayed in the production environment
[Docker] How to build when the source code is bind-mounted on the container
How to solve the local environment construction of Ruby on Rails (MAC)!
[Swift] How to set an image in the background without using UIImageView.
[Ruby] How to prevent errors when nil is included in the operation
[Rails] How to solve the time lag of created_at after save method
[Rails] What to do when the Refile image is not displayed when writing the processing at the time of Routing Error
[Rails] devise customization. How to change the redirect page after user registration and editing, and how to skip password input when editing
How to resolve the error'ActionView :: Template :: Error (The asset "application.css" is not present in the asset pipeline.'" When precompiling Rails assets
What to do about "A server is already running ..." that happened without turning off the rails server in the terminal