ruby on rails - Rails 3의 lib 폴더에서 모듈/클래스를로드하는 가장 좋은 방법은 무엇입니까?




rails lib folder autoload (8)

자동 로딩 물건의 마술

autoloading stuff가 수행되는 폴더를 제어하는 ​​옵션이 다른 답변에서 충분히 다루어 졌다고 생각합니다. 그러나 필요에 따라 자동로드 경로가 수정되었지만 다른 사람이 문제가 발생하는 경우이 대답은이 자동로드 작업의이면에있는 마법에 대해 설명하려고 시도합니다.

따라서 하위 디렉토리의 내용을로드 할 때 잡아 당기는 일이나 규칙을 알아야합니다. 때로는 Ruby / Rails 마법 (이번에는 대부분 Rails)으로 인해 무언가가 일어나는 이유를 이해하기 어려울 수 있습니다. autoload 경로에 선언 된 모듈은 모듈 이름이 상위 디렉토리 이름과 일치하는 경우에만로드됩니다. 그래서 당신이 lib/my_stuff/bar.rb 와 같은 것을 넣으려고한다면 :

module Foo
  class Bar
  end
end

자동으로로드되지 않습니다. 그런 다음 부모 dir의 이름을 foo 변경하면 경로 : lib/foo/bar.rb 에서 모듈을 호스팅합니다. 그것은 당신을 위해있을 것입니다. 또 다른 옵션은 자동로드하려는 파일의 이름을 모듈 이름으로 지정하는 것입니다. 분명히 그 이름으로 하나의 파일 만있을 수 있습니다. 당신의 파일을 여러개의 파일로 나눌 필요가있는 경우에는 그 하나의 파일을 다른 파일을 필요로하기 위해 사용할 수 있지만, 개발 모드에서 그 다른 파일을 수정할 때 레일스가 자동적으로 할 수 없으므로 나는 추천하지 않는다. 그들을 위해 다시로드하십시오. 그러나 실제로 원한다면 모듈 이름별로 하나의 파일을 가질 수 있으며 그 다음 모듈을 사용하는 데 필요한 실제 파일을 지정합니다. 따라서 두 파일을 가질 수 있습니다 : lib/my_stuff/bar.rblib/my_stuff/foo.rb 그리고 이전은 위와 같고 후자는 한 줄을 포함합니다 : require "bar" 는 똑같이 작동합니다.

추신 : 나는 한 가지 더 중요한 것을 추가해야한다고 느낀다. 최근에 lib 디렉토리에 자동로드가 필요한 항목이 필요할 때마다 필자는이 항목이 실제로이 프로젝트를 위해 구체적으로 개발하고 있다면 생각하기 시작하는 경향이 있습니다 (일반적으로, 언젠가는 많은 프로젝트 또는 자식 하위 모듈에서 사용되는 코드의 "정적"스 니펫으로 전환합니다.이 경우 lib 폴더에 있어야합니다. 그런 다음 해당 위치는 lib 폴더에 없습니다. 아마도 앱 폴더 아래의 하위 폴더에 있어야합니다. •이 작업이 새로운 레일 방식이라는 느낌이 들었습니다. 분명히, 당신이 물건을 넣는 경로를 자동로드하는 곳이면 어디에나 똑같은 마술이 작동합니다. 어쨌든, 이것은 주제에 대한 제 생각입니다. 당신은 동의 할 자유입니다. :)

업데이트 : 마술의 종류에 대해 ..

severin이 그의 코멘트에서 지적했듯이 핵심 "autoload a module mechanism"은 Ruby의 일부이지만 물론 자동로드 경로는 그렇지 않습니다. autoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar") 를 수행하기 위해 Rails가 필요하지 않습니다 autoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar") . 그리고 처음으로 Foo 모듈을 참조하려고 할 때, Foo 모듈이로드 될 것입니다. 그러나 Rails가하는 일은 등록 된 폴더에서 자동으로 항목을로드하고로드하는 방법을 제공하며 이름 지정 규칙에 대해 어떤 가정을해야하는 방식으로 구현되었습니다. 이와 같이 구현되지 않았다면, 현재로드되지 않은 것을 참조 할 때마다 모든 자동로드 폴더의 모든 파일을 검토하고 참조하려는 내용이 포함되어 있는지 확인해야합니다. 이것은 차례로 자동로드 및 자동로드라는 아이디어를 무력화시킵니다. 그러나 이러한 규칙을 사용하면 모듈 / 클래스에서로드하려고하는 위치에서 해당 위치가 정의되고로드 될 수있는 위치를 차감 할 수 있습니다.

최신 Rails 3 릴리스는 lib에서 모듈 및 클래스를 자동로드하지 않기 때문에로드하는 가장 좋은 방법은 무엇입니까?

github에서 :

A few changes were done in this commit:

Do not autoload code in *lib* for applications (now you need to explicitly 
require them). This makes an application behave closer to an engine 
(code in lib is still autoloaded for plugins);

config.autoload_paths가 작동하지 않습니다. 나는 다른 방법으로 그것을 해결한다.

루비 온 레일즈 3는 / lib 폴더에서 자동으로 코드를 다시로드 (자동로드)하지 않습니다. ApplicationController 내부에 넣어서 해결했습니다.

Dir["lib/**/*.rb"].each do |path|
  require_dependency path
end 

경고 : 'monkey patch'또는 'lib'폴더에서 'open class'를 로드 하려면 'autoload'접근 방식을 사용하지 마십시오!

  • " config.autoload_paths "접근 : 오직 한 곳에 정의 된 클래스를로드하는 경우에만 작동합니다. 일부 클래스가 이미 다른 곳에 정의 된 경우이 접근 방식으로 다시로드 할 수 없습니다.

  • " config/initializer/load_rb_file.rb "접근법 : 항상 작동합니다! 대상 클래스가 새로운 클래스이거나 기존 클래스의 "공개 클래스"또는 "원숭이 패치"인 경우 항상 작동합니다!

자세한 내용은 다음을 config/initializer/load_rb_file.rb 하십시오. config/initializer/load_rb_file.rb


나는 똑같은 문제가 있었다. 여기 내가 어떻게 해결 했는가. 이 솔루션은 lib 디렉토리와 모든 서브 디렉토리 (직접 디렉토리뿐만 아니라)를로드합니다. 물론 이것을 모든 디렉토리에 사용할 수 있습니다.

# application.rb
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]

특정 파일 만 lib의 모듈에 액세스해야하는 경우 필요로하는 파일에 require 문을 추가하기 만하면됩니다. 예를 들어, 한 모델이 하나의 모듈에 액세스해야하는 경우 다음을 추가하십시오.

require 'mymodule'

model.rb 파일 맨 위.


필자의 경우 lib 디렉토리 아래에 파일을 간단히로드하려고했습니다.

application.rb 내에서 ...

require '/lib/this_file.rb' 

콘솔에서도 작동하지 않았고 시도한 후

require './lib/this_file.rb' 

레일은 파일을 완벽하게로드합니다.

나는 아직도 꽤 멍청하고 왜 이것이 작동하는지 잘 모르겠지만 작동합니다. 누군가가 나에게 설명하고 싶다면 감사하겠습니다. DI는 누군가에게 도움이되기를 바랍니다.


Rails 5 부터 lib 디렉토리를 app 디렉토리에 두거나 그 대신 services , presenters , features 등으로 다른 의미있는 이름 공간을 만들고 레일을 통한 자동 로딩을위한 app 디렉토리 아래에 두는 것이 좋습니다.

GitHub 토론 링크 도 확인하십시오.


파일 이름을 정확하게 기입하십시오.

진지하게. 클래스가 Governance :: ArchitectureBoard이고 파일이 lib / governance / architecture_baord.rb에 있었기 때문에 한 시간 동안 클래스와 전투를 벌였습니다 ( "보드"에서는 O와 A를 전 환했습니다).

돌이켜 보면 분명하지만 악마가 그것을 추적했다. Rails가 클래스 이름을 munging한다고 기대하는 파일에 클래스가 정의되어 있지 않으면 단순히 찾지 않을 것입니다.





ruby-on-rails-3