Last active
April 6, 2022 12:56
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# == 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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