[ruby-on-rails] Rails 4에서 lib 파일 자동 로딩

/lib개발하는 동안 이니셜 라이저에서 다음 줄을 사용하여 디렉토리에 코드를 자동로드합니다 .

config / initializers / custom.rb :

RELOAD_LIBS = Dir[Rails.root + 'lib/**/*.rb'] if Rails.env.development?

( Rails 3 Quicktip : 개발 모드에서 lib 폴더 자동 다시로드 )

훌륭하게 작동하지만 프로덕션 환경에서 사용하기에는 너무 비효율적입니다. 각 요청마다 lib를로드하는 대신 시작 시로 드하려고합니다. 동일한 블로그에는 이를 수행하는 방법을 설명하는 다른 기사 가 있습니다.

config / application.rb :

# Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]

그러나 개발로 전환해도 lib 함수를 사용하려고하면 NoMethodErrors가 발생합니다.

내 lib 파일 중 하나의 예 :

lib / extensions.rb :

Time.class_eval do
  def self.milli_stamp
    Time.now.strftime('%Y%m%d%H%M%S%L').to_i
  end
end

호출 Time.milli_stamp하면 NoMethodError가 발생합니다.

나는 다른 사람들이 SO에 대해 비슷한 질문에 대답했다는 것을 알고 있지만, 그들은 모두 명명 규칙과 내가 걱정할 필요가없는 다른 문제를 다루는 것처럼 보입니다. 내 lib 클래스는 이미 요청 당로드를 위해 했습니다. 허가하는 시작 로드. 이것을하는 올바른 방법은 무엇입니까?



답변

이것이 문제를 해결할 수 있다고 생각합니다.

  1. 에서 설정 / application.rb :

    config.autoload_paths << Rails.root.join('lib')

    lib 에서 올바른 명명 규칙을 유지하십시오. .

    lib 디렉토리 / foo.rb :

    class Foo
    end

    lib 디렉토리 / foo는 / bar.rb :

    class Foo::Bar
    end
  2. lib / extensions.rb 와 같은 파일에서 원숭이 패치를 실제로하고 싶다면 하려면 수동으로 필요할 수 있습니다.

    에서 설정 / 초기화 / require.rb :

    require "#{Rails.root}/lib/extensions" 

추신


답변

이것이 질문에 직접 대답하지는 않지만 질문을 완전히 피하는 것이 좋은 대안이라고 생각합니다.

모든 피하려면 autoload_pathseager_load_paths에 “LIB”또는 “응용 프로그램”디렉토리 아래에 “기타”디렉토리를 만들고, 번거 로움을. 평소와 같이 코드를 배치하면 Rails는 모델 파일을로드하고 다시로드하는 것과 같은 방식으로 파일을로드합니다.


답변

이것은 Rails가 클래스 로딩을 처리하는 방법에 대한 솔루션을 검색 할 때이 답변을 찾는 나와 같은 누군가를 도울 수 있습니다 … module 단지 클래스를 정의하는 것이 아니라, 이름이 적절하게 내 이름을 일치 :

lib / development_mail_interceptor.rb 파일에서 (예, Railscast의 코드를 사용하고 있습니다 🙂

module DevelopmentMailInterceptor
  class DevelopmentMailInterceptor
    def self.delivering_email(message)
      message.subject = "intercepted for: #{message.to} #{message.subject}"
      message.to = "myemail@mydomain.org"
    end
  end
end

작동하지만 클래스를 모듈 안에 넣지 않으면로드되지 않습니다.


답변

config.to_prepare를 사용하여 개발 모드의 모든 요청에 ​​대해 원숭이 패치 / 확장 프로그램을로드하십시오.

config.to_prepare do |action_dispatcher|
 # More importantly, will run upon every request in development, but only once (during boot-up) in production and test.
 Rails.logger.info "\n--- Loading extensions for #{self.class} "
 Dir.glob("#{Rails.root}/lib/extensions/**/*.rb").sort.each do |entry|
   Rails.logger.info "Loading extension(s): #{entry}"
   require_dependency "#{entry}"
 end
 Rails.logger.info "--- Loaded extensions for #{self.class}\n"

종료


답변