Một bản sao của xxx đã bị xóa khỏi cây mô-đun nhưng vẫn hoạt động


129

Tôi khá chắc chắn rằng lỗi không liên quan đến nội dung thực tế của TenantIdLoadermô-đun. Thay vào đó, nó có một cái gì đó để làm với ActiveSupportPhụ thuộc.

Tôi dường như không thể vượt qua lỗi này. Từ những gì tôi đã đọc, đó là bởi vì hoặc ActiveRecord::Baselà được tải lại hoặc Company::TenantIdLoaderđang được tải lại, và bằng cách nào đó nó không truyền đạt được điều đó. Giúp tôi với Tôi thực sự muốn có thể nâng cấp lên Rails 4.2.

BIÊN TẬP

Bây giờ tôi đã biết rằng đó là vì tôi đang tham khảo Tenantđang được tải lại tự động. Tôi cần phải có khả năng thực sự tham khảo lớp học, vậy có ai biết làm thế nào để khắc phục điều này không?

cấu hình / ứng dụng.rb

config.autoload_paths += %W( #{config.root}/lib/company )

cấu hình / khởi tạo / company.rb

ActionMailer::Base.send(:include, Company::TenantIdLoader)

lib / công ty / 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
Câu trả lời này có giúp ích gì không? stackoverflow.com/questions/17561697/
Mạnh

Bạn có chắc là lớp Người thuê nhà có liên quan? Nếu bạn bỏ đi các bit của mã đó sử dụng Tenant, bạn vẫn gặp lỗi chứ?
Frederick Cheung

@WaynnLue yeah Tôi nghĩ đó là lý do, tôi chỉ không biết cách khắc phục.
kddeisz

@FrederickCheung Tôi đã có một tệp khác tương tự như tệp này bị lỗi theo cùng một cách và nó luôn bị lỗi trên dòng liên quan đến Người thuê nhà, vì vậy đó là phỏng đoán tốt nhất của tôi.
kddeisz

1
Mặc dù bạn không sử dụng Wisper in Rails ở đây, nhưng có thể hữu ích cho những người khác lưu ý rằng Wisper gây ra vấn đề này khá nhất quán nếu bạn không làm theo lời khuyên trong chủ đề này: stackoverflow.com/questions/28346609/ trộm
Steve N

Câu trả lời:


181

Tenantlà một loại cá trích đỏ - lỗi sẽ xảy ra nếu bạn tham chiếu bất kỳ bit ứng dụng nào cần được tải bằng const_missingthủ thuật của đường ray .

Vấn đề là bạn đang lấy thứ gì đó có thể tải lại (mô-đun của bạn) và sau đó đưa nó vào thứ gì đó không thể tải lại được ( ActiveRecord::Basehoặc, trong ví dụ trước đó của bạn ActionMailer::Base). Tại một số điểm, mã của bạn được tải lại và bây giờ ActiveRecord vẫn có mô-đun này đi kèm trong đó mặc dù các rails nghĩ rằng nó đã tải nó. Lỗi xảy ra khi bạn tham chiếu Người thuê nhà vì điều đó khiến đường ray chạy các const_missingmóc của nó để tìm ra nơi mà Người thuê nên được tải từ đó và mã đó bị lỗi vì mô-đun nơi bắt đầu tìm kiếm liên tục không nên ở đó.

Có 3 giải pháp khả thi:

  1. Dừng đưa mô-đun của bạn vào các lớp không thể tải lại - bao gồm vào các mô hình riêng lẻ, bộ điều khiển khi cần hoặc tạo một lớp cơ sở trừu tượng và bao gồm mô-đun trong đó.

  2. Làm cho mô-đun này không thể tải lại được bằng cách lưu trữ nó ở một nơi không có trong autoload_paths (bạn sẽ phải yêu cầu nó rõ ràng vì đường ray sẽ không còn tải nó một cách kỳ diệu cho bạn)

  3. Thay đổi đối tượng thuê thành :: Người thuê nhà ( Object.const_missingsau đó sẽ được gọi, không Tenant.const_missing)


30
Tôi dường như đã tìm thấy một giải pháp thứ ba, mặc dù tôi đã tự hỏi nếu bạn biết tại sao nó hoạt động. Nếu tôi tham khảo nó là :: Người thuê nhà, mọi thứ sẽ diễn ra một cách kỳ diệu. Có thể bởi vì sau đó nó tải nó như một hằng số cấp cao nhất? Có lẽ?
kddeisz

3
sau đó, đó là Object.const_missing sẽ được gọi không phải YourModule.const_missing để mọi việc diễn ra tốt đẹp
Frederick Cheung

6
Sao lưu để sử dụng cấp cao nhất cũng ::làm việc cho tôi!
Alex Moore-Niemi

7
Tôi đã có vấn đề này xảy ra theo thời gian và trong trường hợp của tôi nó có liên quan đến mùa xuân, vì vậy làm ./bin/spring stoplà giải quyết nó.
santuxus

1
Tôi YÊU rằng đây là lỗi Ruby / Rails trong thời gian chạy - không giống như bất kỳ ngôn ngữ nào khác, động hay không, Ruby cung cấp cho các nhà phát triển tính linh hoạt không giới hạn thực sự để không có ý nghĩa về việc mô-đun được xác định cho đến khi chương trình của bạn thực thi (và theo thứ tự nó thực thi). Nó được thiết kế rất tốt.
Andy Ray


6

Không chắc điều này có giúp được ai không, nhưng tôi đã có điều này đột nhiên bắt đầu xảy ra sau một thay đổi dường như không liên quan. Nó biến mất sau khi tôi khởi động lại máy chủ ứng dụng.


0

Thay đổi ModuleNameđể 'ModuleName'.constantizegiải quyết vấn đề cho tôi.


0

Điều gì làm việc cho tôi:

Cập nhật config.eager_load = false lêntrue

trong config/environments/development.rb

Ruby 2.6.5 Đường
ray 5.1.6


1
Vâng chắc chắn không làm điều này. Điều đó sẽ giết chết khả năng tải lại mã của bạn trong quá trình phát triển.
kddeisz

-13

Đôi khi bạn chỉ

Khởi động lại máy chủ của bạn,


Tôi không hiểu tại sao downvote câu trả lời này? Lặp lại có nghĩa là nó quan trọng! Tại sao những điều đơn giản có rất nhiều điều vô nghĩa?
Albert.Qing 4/12/18

7
Điều này được đánh giá thấp bởi vì (a) cho dù bạn khởi động lại máy chủ bao nhiêu lần thì nó cũng không giải quyết được vấn đề trong câu hỏi ban đầu và (b) bạn không nên đơn giản xử lý các triệu chứng của một vấn đề, mà chính là vấn đề.
tjbp

@tjbp plz cẩn thận về từ "đôi khi" ok?
Albert.Qing 5/12/18

vấn đề là không thể gỡ lỗi ứng dụng trong chế độ phát triển nếu bạn phải khởi động lại máy chủ sau mỗi thay đổi.
Tối đa Ivak

2
Tôi sẽ bỏ phiếu cho câu trả lời này vì nếu bạn đang sử dụng mongoid và xóa đối tượng X khỏi bảng điều khiển rails, bạn sẽ gặp lỗi này: A copy of X has been removed from the module tree but is still activetại tất cả các trang có Object Y.embeds Xvà máy chủ khởi động lại thực sự hoạt động cho trường hợp cụ thể này. Nhưng bạn nên chỉnh sửa câu trả lời của bạn.
Lucas Andrade
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.