猴子修补ActiveStorage :: Attachment丢失

时间:2019-03-11 20:17:36

标签: ruby-on-rails ruby ruby-on-rails-5 monkeypatching rails-activestorage

因此,我决定将url attr_accessor添加到ActiveStorage :: Attachment对象。

development 中,该补丁会保留一段时间,直到看起来“丢失”为止。这意味着它可以工作几分钟,然后不再工作。然后,我需要重新启动服务器才能再次应用补丁。我相信我没有正确打补丁,因此我需要在该方面提供建议。


这是我尝试过的:

lib / ext / active_storage / attachment.rb

第一次尝试:

module ActiveStorageUrl
  extend ActiveSupport::Concern

  included do
    attr_accessor :url
  end
end

ActiveStorage::Attachment.send :include, ActiveStorageUrl

第二次尝试

class ActiveStorage::Attachment < ActiveRecord::Base
  attr_accessor :url
end

顺便提一下,在这两种情况下,它都被加载了:

config / initializers / monkey_patches.rb

require 'ext/active_storage/attachment'

因此,当它正常工作时,我没有错误消息,但是片刻之后出现了“ diseapear”补丁(缺少更好的术语),并且出现了以下错误,告诉我我的attr_accessor不再存在。 Rails必须重新加载了ActiveStorage类,并且我的补丁丢失了。

Module::DelegationError in Products#images
url delegated to blob, but blob is nil

3 个答案:

答案 0 :(得分:4)

我将ActiveStorage::Attachment MonkeyPatch放置在 / app / models / active_storage /
我添加了一个回调以通知附件是否已更改。一直都能正常工作。

也许是问题所在。

答案 1 :(得分:2)

似乎与delegate_missing_to有关,例如

delegate_missing_to :blob

https://github.com/rails/rails/blob/master/activestorage/app/models/active_storage/attachment.rb#L14

转到where it's defined

无论如何,它可能与attr_accessor的工作方式有关,我会尝试:

def url
  @url
end

def url=(url)
  @url = url
end

代替attr_accessor(实际上是C函数)。

否则,解决此问题的一种真正非常hacky的方法是检查ActiveStorage::Attachment.instance_methods.include?(:url)和猴子补丁/包含/在不存在时添加。

答案 2 :(得分:2)

您可能会丢失猴子补丁,因为重新加载了代码并且不需要 ext / active_storage / attachment

您可以告诉Rails在启动时运行回调,并且每次这样重新加载代码时都如此。

Rails.configuration.to_prepare do
  require 'ext/active_storage/attachment'
end