Rails 5 : 프로덕션 환경에서 lib 파일로드


128

내 앱 중 하나를 Rails 4.2.6에서 Rails 5.0.0으로 업그레이드했습니다. 업그레이드 가이드 자동로드 기능이 기본으로 생산에서 비활성화되어 있음을 말한다.

이제 파일에 자동로드가있는 모든 lib 파일을로드하기 때문에 항상 프로덕션 서버에서 오류가 발생 application.rb합니다.

module MyApp
    class Application < Rails::Application
        config.autoload_paths += %W( lib/ )
    end
end

지금은 config.enable_dependency_loading~을 설정 true했지만 더 나은 해결책이 있는지 궁금합니다. 프로덕션 환경에서는 기본적으로 자동 로딩이 비활성화되어 있어야합니다.


미친 짓과 문서는 여전히 auto_load를 수행하도록 지시합니다. 새로운 앱의 프로덕션 환경에서 무엇이 잘못되고 있는지 매우 혼란 스러웠습니다. Rails 5를 배우기 시작한 이후로 마이그레이션 가이드를 읽지 않았습니다. : 나는 희망이 해결 얻을 수있는 문서의 문제를 제기 github.com/rails/rails/issues/27268
akostadinov

1
놀랍게도, 나는 lib디렉토리에 두 개의 파일이 있는데 , 하나의 파일은 런타임에서 쉽게 사용할 수 있지만 다른 파일은 수동으로 요구해야합니다 : D
illusionist

@Tobias 어떤 솔루션을 찾았습니까?
geoboy

@geoboy Validators코드가 자동으로로드되기 때문에 app / 디렉토리의 폴더에 직접 코드 (예 :)를 그룹화합니다 .
Tobias

그것은 관하여 적절한 파일 경로와 클래스 정의 파일 경로 : 레일 5.2에서 무엇을 나를 위해 일을 여기에 app/services/paylinx/paylinx_service.rb클래스 정의 : module Paylinx class PaylinxService end end. 나는 이것들을 시도했다 autoload_paths. 나를 위해 작동하지 않습니다.
NamNamNam

답변:


161

Rails 5로 이동 한 후의 변경 사항 목록 :

  1. 장소 lib에 디렉토리 app응용 프로그램 내부의 모든 코드가 있기 때문에 자동으로 적재 dev에와 열망로드 가장 중요한 자극과입니다 autoreloaded 는 서버에게 당신이 바꿀 때마다 아파치를 재시작 할 필요가 없습니다 개발.
  2. 파일 / 디렉토리 이름이 올바른 경우 어쨌든 모두 자동으로로드되므로 require내부 클래스를 가리키는 명령문을 제거하십시오. 명령문 lib을 남겨두면 자동 재로드 require가 중단 될 수 있습니다. 더 많은 정보는 여기에
  3. 개발 config.eager_load = true환경에서 코드 로딩 문제를 간절히하도록 모든 환경에서 설정 하십시오.
  4. Rails.application.eager_load!"순환 종속성"오류를 피하기 위해 스레드를 가지고 놀기 전에 사용하십시오 .
  5. 루비 / 레일 확장명을 가진 경우 해당 코드를 이전 lib디렉토리에 그대로두고 초기화 프로그램에서 수동으로로드하십시오. 이렇게하면 확장에 의존 할 수있는 추가 논리 전에 확장을로드 할 수 있습니다.

    # config/initializers/extensions.rb
    Dir["#{Rails.root}/lib/ruby_ext/*.rb"].each { |file| require file }
    Dir["#{Rails.root}/lib/rails_ext/*.rb"].each { |file| require file }

8
그렇다면 lib이제 폴더를 어떻게 사용 합니까? libdir을 dir로 옮기는 app것은 일종의 해결 방법처럼 보입니다.
Martin Svoboda

3
/app/lib/파일 / 클래스를 배치했으며 자동로드되지 않습니다. 레일스 5.1에서 테스트, 새 프로젝트
Tim Kretschmer 2016 년

29
봄을 멈추어야한다는 점은 주목할 가치가 있습니다. 나는 모든 것을 app / lib /로 옮긴 다음 왜 여전히 콘솔에서 수업을 사용할 수 없는지 궁금해했습니다. spring stop ftw :)
jacklin

1
다음 줄은 어디로 Rails.application.eager_load!
Steven Aguilar

1
이것은 작동하지만 최선의 해결책은 아닙니다. 폴더 구조도 의미가 있습니다. 의 것들과 디렉토리의 lib것들과는 프로젝트에 대한 친밀감이 다릅니다 app. 다른 답변들 중 몇 가지는 이것보다 낫습니다.
CWitty 2016 년

84

방금 github 댓글에 akostadinov라는 언급 config.eager_load_paths대신 사용 했습니다 config.autoload_paths: https://github.com/rails/rails/issues/13142#issuecomment-275492070

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

개발 및 프로덕션 환경에서 작동합니다.

감사합니다 요한 제안을 대체 할 #{Rails.root}/lib함께 Rails.root.join('lib')!


3
매력처럼 작동합니다. 구문이 마음에 들지 않아로 변경했습니다 config.eager_load_paths << Rails.root.join('lib').
3limin4t0r

2
나에게 그것은 가장 좋은 대답이었다. 내 프로젝트는 Rails 5.2에서 처음부터 시작되었고 / lib 폴더는 여전히 / app 폴더 외부에 생성되었습니다. 나는 그것을 움직일 좋은 이유를 보지 못했습니다.
사미르 하다드

1
그렇습니다. Rails 개발자들은 다음 번에 lib 로딩 문제를 일으키는 것을 즐깁니다.
Damien Roche

고정 된 배열 config.eager_load_paths += [Rails.root.join('lib')]이기 때문에 To Rails 5.2가 대신 사용 합니다 config.eager_load_paths
William Wong Garay

@WilliamWongGaray config.eager_load_paths는 초기화 프로그램에서 수정하려고 할 때 읽기 전용입니다. 경로를 추가하면 application.rb두 가지 방법을 모두 사용합니다.
Michał Zalewski

31

스레드 안전으로 인해 프로덕션 환경에서 자동로드가 비활성화되었습니다. 링크를 위해 @ Зелёный에게 감사합니다.

Github에서 권장하는대로 lib 파일 lib을 내 app디렉토리 의 폴더에 저장 하여이 문제를 해결했습니다 . 폴더의 모든 폴더는 Rails에 의해 자동으로로드됩니다.app


6
당신이 Github에서 긴 토론 스레드를 통해 발굴하지 않으려면, 당신은 여기에 증류수 설명을 찾을 수 있습니다 collectiveidea.com/blog/archives/2016/07/22/...
어니스트

7
내가 사용 config.eager_load_paths << "#{Rails.root}/lib"권장 레일 응용 프로그램 구조를 따라 더 나은 IMO의 그.
akostadinov

2
lib에 퍼팅 app/lib레일을 추천 한 회원 github.com/rails/rails/issues/13142#issuecomment-275549669
EXA

4
이것은 목적이 무엇인지 완전히 파멸시킵니다 lib. 나는 tenderlove 또는 DHH가 들릴 때까지 기다릴 것입니다. 그 동안 개인적으로 @Lev Lukomsky의 답변을 고수하는 것이 좋습니다.
Josh Brody

@JoshBrody 내 의견은 이제 /lib디렉토리 가 전혀 필요 없다는 것입니다. 타사 라이브러리는 대부분의 시간 보석이며 그렇지 않은 경우 보석이 생성됩니다. 다른 파일의 경우 /app디렉토리에 특정 폴더를 만듭니다 . 예를 들면 validators.
Tobias


12

이를 통해 lib 자동 재로드가 가능하며 프로덕션 환경에서도 작동합니다.

추신 : 나는 대답을 변경했다. 이제 환경과 무관하게 열렬한 자동로드 경로에 추가하여 무대와 같은 사용자 정의 환경에서도 작업 할 수 있도록합니다.

# config/initializers/load_lib.rb
...
config.eager_load_paths << Rails.root.join('lib')
config.autoload_paths << Rails.root.join('lib')
...

2
이것이 문제를 해결하는 이유를 확장 할 수 있습니까?
Stuart.Sklinar

@ Stuart.Sklinar는 lib 자동 재로드를 허용하며 프로덕션 환경에서도 작동합니다. 추신 : 나는 내 대답을 변경했습니다. 이제 환경과 상관없이 사용자 정의 환경에서도 작업을 허용하기 위해 열렬한 자동로드 경로에 추가합니다 (단계와 같은)
srghma

1
(답으로) 확장 할 수 있습니까? 코드 만 대답은 왜 "그런 식으로"해야하는지 이해하는 데 도움이되지 않습니다. 루비 개발자가 아니라 SO를 정리하는 데 도움이됩니다. "code only answer"에 주석을 추가하면 실제 상황을 알 수 있습니다.
Stuart.Sklinar

1
@ Stuart.Sklinar sure
srghma

6

config / application.rb 파일에서 config.autoload_pathsconfig.eager_load_paths 로 변경 하십시오. Rails 5에서는 기본적으로 프로덕션 환경에서 자동 로딩이 비활성화되어 있습니다. 자세한 내용은 링크 를 참조하십시오 .

 #config.autoload_paths << "#{Rails.root}/lib"
  config.eager_load_paths << Rails.root.join('lib')

환경 개발과 프로덕션 모두에서 작동합니다.


4

어떤 의미에서, Rails 5에는 열악한 자동로드 구성을 중앙 집중화하는 통합 된 접근 방식이 있으며, 동시에 열성적인로드가 구성 될 때마다 필요한 자동로드 경로를 추가하면 제대로 작동하지 않습니다.

# config/application.rb
...
config.paths.add Rails.root.join('lib').to_s, eager_load: true

# as an example of autoload only config
config.paths.add Rails.root.join('domainpack').to_s, autoload: true
...

2

나처럼이 문제로 어려움을 겪고있는 사람은 디렉토리를 아래에 두는 것만으로는 충분하지 않습니다 app/. 그렇습니다. 자동 로딩이 가능하지만 다시로드 할 필요는 없습니다 . 네임 스페이스 규칙을 준수해야 합니다.

또한 이니셜 라이저를 사용하여 이전 루트 레벨로드 lib 하면 개발 중에 다시로드 기능을 사용할 수 없습니다.


0

lib 폴더를 앱으로 이동하면 문제를 해결하는 데 도움이되었으므로 Twitter API가 프로덕션에서 실행되지 않습니다. 나는 "초기화되지 않은 상수 TwitterApi"를 가지고 있었고 트위터 API는 내 lib 폴더에 있었다. 나는했다config.autoload_paths += Dir["#{Rails.root}/app/lib"] 나의 application.rb에 있지만 폴더를 이동하기 전에 작동하지 않았다.

이 트릭을했다


-6

레프의 답변을 요약 : mv lib app모든이에 충분했다 내lib 코드를 자동로드 / 자동 다시로드 .

(레일 6.0.0beta3이지만 레일 5.x에서도 잘 작동합니다)

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