So I decided to add an url
attr_accessor to ActiveStorage::Attachment objects.
In development the patch holds for a while until it seems to "have been lost". Meaning it works for few minutes, then it does not work anymore. Then I need to restart the server in order to get the patch applied again. I believe I am not patching correctly and I would need advises in that mater.
Here is what I tried:
lib/ext/active_storage/attachment.rb
First try :
module ActiveStorageUrl
extend ActiveSupport::Concern
included do
attr_accessor :url
end
end
ActiveStorage::Attachment.send :include, ActiveStorageUrl
Second try
class ActiveStorage::Attachment < ActiveRecord::Base
attr_accessor :url
end
And by the way in both case it's loaded with this:
config/initializers/monkey_patches.rb
require 'ext/active_storage/attachment'
So when it work I have no error message, but after a while the patch "diseapear" (lacking better terms), and I get the following error, telling me my attr_accessor is not there anymore. Rails must have reloaded ActiveStorage classes and my patch is lost.
Module::DelegationError in Products#images
url delegated to blob, but blob is nil
Monkey patching is reopening the existing classes or methods in class at runtime and changing the behavior, which should be used cautiously, or you should use it only when you really need to. As Python is a dynamic programming language, Classes are mutable so you can reopen them and modify or even replace them.
Monkey patching is a technique used to dynamically update the behavior of a piece of code at run-time. A monkey patch (also spelled monkey-patch, MonkeyPatch) is a way to extend or modify the runtime code of dynamic languages (e.g. Smalltalk, JavaScript, Objective-C, Ruby, Perl, Python, Groovy, etc.)
I placed my ActiveStorage::Attachment
MonkeyPatch in /app/models/active_storage/
I've added a callback to get informed if the Attachment has changed. It works fine, all the time.
Maybe this is the issue.
You are probably losing your monkey patch because the code gets reloaded and your ext/active_storage/attachment isn't re-required.
You can tell Rails to run a callback at startup and every time code is reloaded like this.
Rails.configuration.to_prepare do
require 'ext/active_storage/attachment'
end
Seems to have to do with delegate_missing_to
, e.g.
delegate_missing_to :blob
https://github.com/rails/rails/blob/master/activestorage/app/models/active_storage/attachment.rb#L14
Going to where it's defined:
Anyway it might have to do with how attr_accessor
works, I would try:
def url
@url
end
def url=(url)
@url = url
end
Instead of attr_accessor
(which is a C function actually).
Otherwise a really really hacky way to solve this would be to check for ActiveStorage::Attachment.instance_methods.include?(:url)
and monkey patch / include / prepend when not present.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With