Reputation: 7533
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]]
Upvotes: 2
Views: 2029
Reputation: 52198
For new rails 7 apps, inside the ActiveStorage migration file, change this
primary_key_type, foreign_key_type = primary_and_foreign_key_types
to this
primary_key_type, foreign_key_type = [:uuid, :uuid]
It will work now.
The ActiveStorage docs says:
If you are using UUIDs instead of integers as the primary key on your models you will need to change the column type of
active_storage_attachments.record_id
andactive_storage_variant_records.id
in the generated migration accordingly.
More reading here for older rails versions.
Upvotes: 1
Reputation: 7533
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
Upvotes: 5