Jestem prawie pewien, że błąd nie ma nic wspólnego z rzeczywistą zawartością TenantIdLoader
modułu. Zamiast tego ma coś wspólnego z ActiveSupport
zależnościami.
Wydaje się, że nie mogę obejść tego błędu. Z tego, co przeczytałem, wynika to z tego, że albo ActiveRecord::Base
jest ponownie ładowany, albo Company::TenantIdLoader
jest ponownie ładowany, i jakoś tego nie przekazuje. Prosimy o pomoc! Naprawdę chciałbym mieć możliwość aktualizacji do Rails 4.2.
EDYTOWAĆ
Teraz dowiedziałem się, że dzieje się tak, ponieważ odwołuję się do tego, Tenant
który jest automatycznie ładowany ponownie. Muszę jednak mieć możliwość odniesienia się do klasy, więc czy ktoś wie, jak to obejść?
config / application.rb
config.autoload_paths += %W( #{config.root}/lib/company )
config / initializers / company.rb
ActionMailer::Base.send(:include, Company::TenantIdLoader)
lib / company / tenant_id_loader.rb
module Company
module TenantIdLoader
extend ActiveSupport::Concern
included do
cattr_accessor :tenant_dependency
self.tenant_dependency = {}
after_initialize do
self.tenant_id = Tenant.active.id if self.class.tenant_dependent? and self.new_record? and Tenant.active.present? and !Tenant.active.zero?
end
end
# class methods to be mixed in
module ClassMethods
# returns true if this model's table has a tenant_id
def tenant_dependent?
self.tenant_dependency[self.table_name] ||= self.column_names.include?('tenant_id')
end
end
end
end
źródło
Odpowiedzi:
Tenant
to coś w rodzaju czerwonego śledzia - błąd wystąpiłby, gdybyś odwołał się do dowolnego fragmentu aplikacji, który musi zostać załadowany przezconst_missing
sztuczkę railsów.Problem polega na tym, że bierzesz coś, co można przeładować (twój moduł), a następnie dołączasz to do czegoś, czego nie można przeładować (
ActiveRecord::Base
lub we wcześniejszym przykładzieActionMailer::Base
). W pewnym momencie twój kod jest przeładowywany i teraz ActiveRecord nadal zawiera ten moduł, mimo że railsy myślą, że go wyładował. Błąd występuje, gdy odwołujesz się do dzierżawcy, ponieważ powoduje to, że szyny uruchamiają swojeconst_missing
punkty zaczepienia, aby dowiedzieć się, skąd dzierżawca powinien zostać załadowany, a ten kod przestaje działać, ponieważ moduł, od którego rozpoczyna się ciągłe wyszukiwanie, nie powinien tam być.Istnieją 3 możliwe rozwiązania:
Przestań włączać swój moduł do klas, których nie można przeładowywać - albo dołącz do indywidualnych modeli, kontrolerów w razie potrzeby, albo utwórz abstrakcyjną klasę bazową i dołącz do niej moduł.
Spraw, aby ten moduł nie był przeładowywalny, przechowując go w miejscu, które nie znajduje się w autoload_paths (będziesz musiał go jawnie wymagać, ponieważ szyny nie będą już ładowały go magicznie)
Zmiana Tenant na: Tenant (
Object.const_missing
zostanie wywołana, a nieTenant.const_missing
)źródło
::
działało dla mnie!./bin/spring stop
było jego rozwiązaniem.Zmiana ModuleName na :: ModuleName działała dla mnie.
źródło
Nie jestem pewien, czy to komuś pomoże, ale nagle zaczęło się to dziać po zmianie, która wydawała się niezwiązana. Zniknął po zrestartowaniu serwera aplikacji.
źródło
Zmiana,
ModuleName
aby'ModuleName'.constantize
rozwiązać problem za mnie.źródło
Co mi pomogło:
Zaktualizuj
config.eager_load = false
dotrue
w
config/environments/development.rb
Ruby 2.6.5
Rails 5.1.6
źródło
Czasami po prostu
Uruchom ponownie serwer,
źródło
A copy of X has been removed from the module tree but is still active
na wszystkich stronach, które mają ObjectY.embeds X
i restart serwera, naprawdę działa w tym konkretnym przypadku. Ale powinieneś zmienić swoją odpowiedź.