'Can't resolve image into URL: to_model delegated to attachment, but attachment is nil in Rails 5.2

I have the following form:

<%= form_with(model: user, local: true) do |form| %>
  <% if user.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>

      <ul>
      <% user.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.file_field :avatar %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

It is being called on my edit page:

<h1>Upload Avatar</h1>
  <%= image_tag(@user.avatar) %>
  <%= render 'form', user: @user %>
<hr>

I get the error in the title but I am not sure why the avatar is not being attachd to the user model. I have all the requirements done for active_storage.

has_one_attached :avatar in user model.

In user controller:

  def identity_params
    params.permit(:email_confirmation, :password, :password_confirmation, :avatar).to_h.symbolize_keys.tap do |params|
      params[:email] = params[:email_confirmation]
    end 
  end 

Also I have all the necessary migrations. Am I missing the actual avatar attaching logic?



Solution 1:[1]

It seems you are missing configuration (because you don't mention it):

You must declare Active Storage services in config/storage.yml

Example from docs:

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

amazon:
  service: S3
  access_key_id: ""
  secret_access_key: ""

and you must tell Active Storage which service to use by setting Rails.application.config.active_storage.service

Because each environment will likely use a different service, it is recommended to do this on a per-environment basis. To use the disk service from the previous example in the development environment, you would add the following to config/environments/development.rb:

# Store files locally.
config.active_storage.service = :local

Solution 2:[2]

Soultion if your user model id is UUID

You need to modify ActiveStorage migration a bit by adding type: :uuid to ActiveStorage migration by record field

create_table :active_storage_attachments do |t|
  t.string     :name,     null: false
  t.references :record,   null: false, polymorphic: true, index: false, type: :uuid
  ...

reference https://edgeguides.rubyonrails.org/active_storage_overview.html#setup

Solution 3:[3]

I was also facing the same error due to the silly mistake. Actually I added the extra space to local: key. So make sure you are following the proper indentation. And should not miss the configuration. You must declare Active Storage services in config/storage.yml in the following way.

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

amazon:
  service: S3
  access_key_id: ""
  secret_access_key: ""
  bucket: ""
  region: "" # e.g. 'us-east-1'

Make sure in the environment/development.rb, environment/production.rb and environment/test.rb you have added the following line of code

config.active_storage.service = :local #environment/development.rb
config.active_storage.service = :amazon ##environment/production.rb
config.active_storage.service = :test #environment/test.rb

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Paulo Belo
Solution 2 ToTenMilan
Solution 3 Jitendra Rathor