Search code examples
ruby-on-railsrails-activestorage

Rails Active Storage not working every time. Some time it works, sometime it doesn't


I am using Active Storage to store images for match score. My class looks like this

class TournamentMatch < ApplicationRecords
  has_many_attached :score_cards
end

My Score card controller looks like this

class Public::ScoreCardsController < Public::BaseController
  def new
    session[:tournament_match_id] = params[:tournament_match_id]
  end

  def create
    tournament_match_id = session[:tournament_match_id]
    tournament_id = session[:tournament_id]
    session[:tournament_match_id] = nil
    session[:tournament_id] = nil

    tournament_match = TournamentMatch.find_by(id: tournament_match_id)

    if tournament_match.score_cards.attach(params['score_cards'])
      flash[:notice] = 'Score card uploaded'
    else
      flash[:error] = 'Score card upload failed'
    end
      
    redirect_to public_results_path(tournament_id: "#{tournament_id}/", anchor: 'results')
  end

  def view
    @tournament_match = TournamentMatch.find_by(id: params[:tournament_match_id])
    render layout: "application"
  end
end

So in my create action,I am finding TournamentMatch by id and then attaching score card to it. I am using same image file each time for uploading. But sometimes image is getting attached and sometime it doesn't. tournament_match.score_cards.attach(params['score_cards'] always returns true in controller. But if i find the same tournament_match and run tournament_match.score_cards.attach(params['score_cards'] in console then it's returning false. I have also noticed that record_id for active_storage_attachments is set to 0 when ever image is not saved. But if image is saved then record_id have value greater than 0.

I have run out of ideas for debugging. Please suggest me how to debug this problem.

Update: below query is from log file, it shows record_id is nil

ActiveStorage::Attachment Exists? (0.6ms)  SELECT 1 AS one FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4  [["record_id", nil], ["record_type", "TournamentMatch"], ["name", "score_cards"], ["LIMIT", 1]]

Solution

  • My main problem was that I am using :uuid for primary key for all my tables so I has to edit ActiveStorage migration to use :uuid. I had changed mainly these 2 lines t.references :record, null: false, polymorphic: true, index: false, type: :uuid and t.references :blob, null: false, type: :uuid. My final migration looks like this. And after this ActiveStorage is now woking fine.

    class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
      def change
        create_table :active_storage_blobs, id: :uuid do |t|
          t.string   :key,        null: false
          t.string   :filename,   null: false
          t.string   :content_type
          t.text     :metadata
          t.bigint   :byte_size,  null: false
          t.string   :checksum,   null: false
          t.datetime :created_at, null: false
    
          t.index [ :key ], unique: true
        end
    
        create_table :active_storage_attachments, id: :uuid do |t|
          t.string     :name,     null: false
          t.references :record,   null: false, polymorphic: true, index: false, type: :uuid
          t.references :blob,     null: false, type: :uuid
    
          t.datetime :created_at, null: false
    
          t.index [ :record_type, :record_id, :name, :blob_id ], name: "index_active_storage_attachments_uniqueness", unique: true
          t.foreign_key :active_storage_blobs, column: :blob_id
        end
      end
    end