Module: Shrine::Plugins::KithePersistedDerivatives::AttacherMethods
- Defined in:
- lib/shrine/plugins/kithe_persisted_derivatives.rb
Instance Method Summary collapse
-
#add_persisted_derivatives(local_files, **options) ⇒ Object
Like the shrine ‘add_derivatives` method, but also persists the derivatives (saves to db), in a realiably concurrency-safe way.
-
#create_persisted_derivatives(*args, storage: nil, allow_other_changes: false, **options) ⇒ Object
Like the shrine ‘create_derivatives` method, but persists the created derivatives to the database in a concurrency-safe way.
-
#remove_persisted_derivatives(*paths, **options) ⇒ Object
Kind of like built-in Shrine #remove_derivatives, but also takes care of persisting AND deleting the removed derivative file from storage – all in concurrency-safe way, including not making sure to overwrite any unrelated derivatives someone else was adding.
Instance Method Details
#add_persisted_derivatives(local_files, **options) ⇒ Object
Like the shrine ‘add_derivatives` method, but also persists the derivatives (saves to db), in a realiably concurrency-safe way.
Generally can take any options that shrine ‘add_derivatives` can take, including custom `storage` or `metadata` arguments.
Like shrine add_derivatives, it will assume the files passed in are temporary, and delete them for you. If you want to disable this behavior:
attacher.add_persisted_derivatives({key: io}, delete: false)
In some cases the derivatives can’t be persisted because the underlying database has changed such that they would not be applicable. In those cases ‘false` will be return value, otherwise returns the new derivatives just as shrine `add_derivatives`
Because the concurrent-safe persistence method will save the associated model – and save without ActiveRecord validation – it is not safe to add_persisted_derivatives on a model with other unsaved changes. The method will by default refuse to do so, throwing a TypeError. If you’d like to force it, pass ‘allow_other_changes: true` as an argument.
Also takes care of deleting any replaced derivative files, that are no longer referenced by the model. Shrine by default does not do this: github.com/shrinerb/shrine/issues/468
All deletions are inline. In general this could be a fairly expensive operation, it can be wise to do it in a bg job.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/shrine/plugins/kithe_persisted_derivatives.rb', line 54 def add_persisted_derivatives(local_files, **) other_changes_allowed = !!.delete(:allow_other_changes) if record && !other_changes_allowed && record.changed? raise TypeError.new("Can't safely add_persisted_derivatives on model with unsaved changes. Pass `allow_other_changes: true` to force.") end existing_derivative_files = nil # upload to storage new_derivatives = upload_derivatives(local_files, **) begin atomic_persist do |reloaded_attacher| # record so we can delete any replaced ones... existing_derivative_files = map_derivative(reloaded_attacher.derivatives).collect { |path, file| file } # make sure we don't override derivatives created in other jobs, by # first using the current up-to-date derivatives from db, # then merging our changes in on top. set_derivatives(reloaded_attacher.derivatives) merge_derivatives(new_derivatives) end rescue Shrine::AttachmentChanged, ActiveRecord::RecordNotFound => e # underlying file has changed or model has been deleted, inappropriate # to add the derivatives, we can just silently drop them, but clean # up after ourselves. delete_derivatives(local_files) unless [:delete] == false delete_derivatives(new_derivatives) return false rescue StandardError => e # unexpected error, clean up our files and re-raise delete_derivatives(local_files) unless [:delete] == false delete_derivatives(new_derivatives) raise e end # Take care of deleting from storage any derivatives that were replaced. current_derivative_files = map_derivative(derivatives).collect { |path, file| file } replaced_files = existing_derivative_files - current_derivative_files delete_derivatives(replaced_files) new_derivatives end |
#create_persisted_derivatives(*args, storage: nil, allow_other_changes: false, **options) ⇒ Object
Like the shrine ‘create_derivatives` method, but persists the created derivatives to the database in a concurrency-safe way.
Can take all options that shrine ‘create_derivatives` can take, including custom processors, custom storage key, and arbitrary custom processor arguments.
asset.file_attacher.create_persisted_derivatives
asset.file_attacher.create_persisted_derivatives(storage: :custom_key)
asset.file_attacher.create_persisted_derivatives(:kithe_derivatives)
asset.file_attacher.create_persisted_derivatives(:kithe_derivatives, some_arg: "value")
asset.file_attacher.create_persisted_derivatives(:kithe_derivatives, alternate_source_file)
Also has an ‘allow_other_changes` argument, see #add_persisted_derivatives.
112 113 114 115 116 117 |
# File 'lib/shrine/plugins/kithe_persisted_derivatives.rb', line 112 def create_persisted_derivatives(*args, storage: nil, allow_other_changes: false, **) return false unless file local_files = process_derivatives(*args, **) add_persisted_derivatives(local_files, storage: storage, allow_other_changes: allow_other_changes) end |
#remove_persisted_derivatives(*paths, **options) ⇒ Object
Kind of like built-in Shrine #remove_derivatives, but also takes care of persisting AND deleting the removed derivative file from storage – all in concurrency-safe way, including not making sure to overwrite any unrelated derivatives someone else was adding.
Can take the same sorts of path arguments as Shrine derivative #remove_derivatives
asset.file_attacher.remove_persisted_derivatives(:small_thumb)
asset.file_attacher.remove_persisted_derivatives(:small_thumb, :large_thumb)
asset.file_attacher.remove_persisted_derivatives(:small_thumb, :large_thumb, allow_other_changes: true)
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/shrine/plugins/kithe_persisted_derivatives.rb', line 129 def remove_persisted_derivatives(*paths, **) return if paths.empty? other_changes_allowed = !!.delete(:allow_other_changes) if record && !other_changes_allowed && record.changed? raise TypeError.new("Can't safely add_persisted_derivatives on model with unsaved changes. Pass `allow_other_changes: true` to force.") end removed_derivatives = nil atomic_persist do |reloaded_attacher| set_derivatives(reloaded_attacher.derivatives) removed_derivatives = remove_derivatives(*paths, delete: false) end if removed_derivatives map_derivative(removed_derivatives) do |_, derivative| derivative.delete if derivative end end removed_derivatives rescue Shrine::AttachmentChanged, ActiveRecord::RecordNotFound # original was already deleted or changed, the derivatives wer'e trying to delete. # It should be fine to do nothing, the process that deleted or changed # the model should already have deleted all these derivatives. # But we'll return false as a signel. return false end |