xxxのコピーがモジュールツリーから削除されましたが、まだアクティブです


129

エラーはTenantIdLoaderモジュールの実際のコンテンツとは何の関係もないと確信しています。代わりに、ActiveSupport依存関係と関係があります。

このエラーを乗り越えられないようです。私が読んだことから、それActiveRecord::BaseはリロードされているかリロードされているためCompany::TenantIdLoaderであり、どういうわけかそれを伝えていません。助けてください!Rails 4.2にアップグレードできるようになりたいです。

編集

Tenantこれは、自動的に再読み込みされるリファレンスを参照しているためです。しかし、実際にクラスを参照できるようにする必要があるので、これを回避する方法を誰かが知っていますか?

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

3
この回答は役に立ちますか?stackoverflow.com/questions/17561697/...
Waynnルー

テナントクラスが関与していることを確認しますか?テナントを使用するコードの一部をスタブアウトしても、エラーが発生しますか?
Frederick Cheung

@WaynnLueええ、それが理由だと思います。修正方法がわかりません。
kddeisz 2015

@FrederickCheung同じようにエラーが発生しているこのファイルに似た別のファイルがあり、それは常にテナントに関連する行でエラーが発生するので、それが私の推測です。
kddeisz 2015

1
あなたがここにRailsのでWisperを使用していないが、それはあなたがこのスレッドでアドバイスに従わない場合Wisperはかなり一貫してこの問題が発生することに注意することは、他の人に役立つことがあります。stackoverflow.com/questions/28346609/...
スティーブN

回答:


182

Tenantこれは一種の赤いニシンです-Railsのconst_missingトリックでロードする必要があるアプリのビットを参照した場合にエラーが発生します。

問題は、リロード可能なもの(モジュール)を取得し、それをリロード不可能なもの(ActiveRecord::Baseまたは以前の例ActionMailer::Base)に含めることです。ある時点でコードがリロードされ、レールがアンロードしたと思っていても、ActiveRecordにはこのモジュールが含まれています。エラーは、Tenantを参照するときに発生します。これにより、レールがconst_missingフックを実行して、Tenantをどこからロードする必要があるかを検出し、定数検索が開始されるモジュールがそこにないため、コードがフリークします。

3つの可能な解決策があります。

  1. モジュールを再読み込み不可能なクラスに含めるのをやめます-必要に応じて個々のモデル、コントローラーに含めるか、抽象基本クラスを作成してそこにモジュールを含めます。

  2. autoload_pathsにない場所にこのモジュールを格納することにより、このモジュールを再ロード不可能にします(レールが魔法のようにモジュールをロードしないため、明示的に要求する必要があります)

  3. テナントを:: Tenantに変更しObject.const_missingます(呼び出されるのではなくTenant.const_missing


30
私は3番目の解決策を見つけたようですが、なぜそれが機能するのか知っているのではないかと思っていました。私がそれを参照した場合::テナント、すべてが魔法のように機能します。おそらくそれがトップレベルの定数としてロードしているためでしょうか?多分?
kddeisz 2015

3
次に、ObjectModule.const_missingではなくObject.const_missingが呼び出されるため、問題は解決します
Frederick Cheung

6
トップレベルの使用に::戻ることも私にとってうまくいきました!
Alex Moore-Niemi

7
私は時々この問題を抱えていましたが、私の場合は春に関連してい./bin/spring stopたので、それを解決することでした。
santuxus 2017

2
これはランタイム Ruby / Railsエラーであることが大好きです-動的かどうかに関係なく、Rubyは開発者に、プログラムが実行されるまで(および実行される順序で)モジュールがどこに定義されているかをまったく知らない、真の無限の柔軟性を提供します。それはとてもよく設計されています。
アンディレイ


6

これが誰かに役立つかどうかはわかりませんが、無関係に思われる変更の後に突然起こり始めました。アプリケーションサーバーを再起動した後、消えました。


0

私のために問題ModuleName'ModuleName'.constantize解決するために変更します。


0

私のために働いたもの:

アップデートconfig.eager_load = falsetrue

config/environments/development.rb

Ruby 2.6.5
Rails 5.1.6


1
ええ、これは絶対にしないでください。これにより、開発中にコードをリロードする機能が無効になります。
kddeisz

-13

時にはあなただけ

サーバーを再起動し、


なぜこの回答に反対票を投じるのか理解できませんか?繰り返しは、それが重要であることを意味します!なぜ単純なものに多くのナンセンスがあるのですか?
Albert.Qing 2018

7
これは、(a)サーバーを何度再起動しても元の質問の問題は解決されないこと、および(b)問題の症状を単に処理するのではなく、問題自体が原因です。
tjbp 2018

@tjbp plz「ときどき」という単語に注意しますか?
Albert.Qing 2018

問題は、変更のたびにサーバーを再起動する必要がある場合、開発モードでアプリケーションをデバッグすることが不可能であることです。
Max Ivak 2018

2
mongoidを使用してオブジェクトXをrails consoleから削除すると、このエラーが発生するため、私はこの回答に投票します。Objectを含むA copy of X has been removed from the module tree but is still activeすべてのページでY.embeds X、この特定のケースでサーバーの再起動が実際に機能します。ただし、回答は編集する必要があります。
Lucas Andrade
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.