Rails 4에서 lib 파일 자동 로딩


229

/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 클래스는 이미 요청 당로드를 위해 했습니다. 허가하는 시작 로드. 이것을하는 올바른 방법은 무엇입니까?


Rails 앱을 시작할 때 config / initializers 폴더가 자동으로로드됩니까?
Jwan622

답변:


548

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

  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" 

추신


1
@ ifyouseewendy- extensions.rb 가 Rails 명명 규칙을 따르지 않았기 때문에 Rails는로드 프로세스에 포함하지 않았습니다. 수동으로 요구하여 작동하게했습니다.
Yarin

@ifyouseewendy 모델을로드하기 전에 파일을 어떻게 포함시킬 수 있습니까? 자동로드하는 경로를 추가하는 것이 좋지만 포함 순서를 어떻게 제어합니까? thx
Matrix

@Matrix "모델을로드하기 전에 파일 포함"에서 자동로드 기능을 사용하지 않고 파일을 수동으로 요구할 수 있습니다.
ifyouseewendy 님이

@ifyouseewendy 초기화 프로그램에서 필요하지만 파일이 autoload_path에 있으면 다시로드 (2 회로드)됩니까? theire는 PHP에서와 같이 "require_once"입니까?
Matrix

5
이것은 프로덕션의 Rails 5 API에서 작동하지 않는 것 같습니다 (그러나 개발에서는). 나는 당신이 사용해야한다고 생각합니다 config.eager_load_paths << Rails.root.join('lib'). 그러나 그것은 eager_load_paths작업의 모든 것을 로드 하는 데 큰 단점이 있습니다. 나는 lulalala의 해결책이 더 낫다고 생각합니다. 자세한 내용의 블로그 게시물은 다음과 같습니다. blog.arkency.com/2014/11/…
hirowatari

33

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

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


3
저는 Rails 4.2에 있습니다. 아래에 있으며로드 파일 자동하지 않습니다 app, 내가 수동으로 할 필요가 ...... 또는 필요가 autload 경로에 넣어 ..
Arup에 Rakshit에게

6
당신은 인 Arup은 응용 프로그램 디렉토리의 하위 디렉터리가 레일 4.2.See의에서 autoload_paths 배열에 자동으로 잘못되어 edgeguides.rubyonrails.org/...
Dr.Strangelove

app/views추가되지 않은 디렉토리를 제외하고 ; 또는 오히려 명시 적으로 제거됩니다.
James B. Byrne

1
좋은 대답입니다. rails 5 / api에서 나를 위해 일한 것만.
jstafford

6
lib여러 프로젝트에 적용될 수 있고 gem으로 추출 될 수있는 코드를위한 것임을 명심하십시오 . 앱 검색에서 더 적합한 폴더를 만들지 않으면 하위 폴더를 만들 services/거나 하위 디렉토리를 만들 presenters/수도 있습니다.
PhilT

6

이것은 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

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


1
루비에서 "적절하게 일치"는 파일이 루비 앱이 사용하는로드 경로 (레일의 경우 autoload_paths LOAD_PATH/module/class.rb) 에있는 파일 시스템 (밑줄로 표시됨 LOAD_PATH)에 있음을 의미합니다. lib는 Rails에 의해 자동로드되지 않아 자동로드되지 않도록 변경되었으며, 최근 버전 (> = Rails 3.x)에서는 자동로드되지 않습니다. 어떤 마술이 당신을 위해이 일을하는 것은 권장하지 않습니다. 아마도 그것은 오래된 Railscast입니까?
피터 H. 볼링

0

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"

종료

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.