Skip to content

Instantly share code, notes, and snippets.

@owen2345
Last active April 6, 2022 12:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save owen2345/c9a275cdaa4ed01fa54da0dce83100eb to your computer and use it in GitHub Desktop.
Save owen2345/c9a275cdaa4ed01fa54da0dce83100eb to your computer and use it in GitHub Desktop.
Rails active storage: Add the ability to rename uploaded file (supports for amazon and local)
# == Schema Information
#
# Table name: photos
#
# id :integer not null, primary key
# position :integer
# created_at :datetime not null
# updated_at :datetime not null
class Photo < ApplicationRecord
has_one_attached :file
after_save_commit :set_filename, if: ->(o) { o.file.blob }
after_update_commit :rename_remote_file, if: :position_previously_changed?
private
def set_filename
file.blob.update!(key: filename, filename: filename)
end
def filename
ext = self.file.filename.extension
"#{id}-pos#{position}.#{ext}"
end
def rename_remote_file
return if !file.blob
if file.service.name == :amazon
obj = file.service.send(:object_for, file.blob.key)
obj.move_to(bucket: obj.bucket.name, key: filename)
else # local
old_path = file.service.path_for(file.blob.key)
new_path = file.service.path_for(filename)
FileUtils.mv(old_path, new_path)
end
end
end
# Samples:
# p = Photo.create!(file: { io: File.open('/my_photo.png') }, position: 1)
# puts p.file.url # ==> /1-pos1.png
# p.update!(position: 2)
# puts p.file.url # ==> /1-pos2.png
require 'rails_helper'
RSpec.describe Photo, type: :model do
describe 'when defining the photo name' do
let!(:photo) { create(:photo, position: 1) }
it 'sets the photo name when file has been added' do
expect(photo.url).to include('_1.jpg')
end
it 'updates photo name when position has changed' do
photo.update!(position: 5)
expect(photo.url).to include('_5.jpg')
end
it 'updates uploaded photo name when position has changed' do
photo.update!(position: 5)
new_path = photo.file.service.path_for(photo.file.blob.key)
expect(File.exist?(new_path)).to be_truthy
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment