Rails / lib 모듈 및


83

open_flash_chart플러그인에 대한 사용자 정의 래퍼를 작성 중 입니다. 에 배치 /lib되고 ApplicationController.

그러나 클래스 계층 구조 또는 smth 문제가 있습니다.

어떤 컨트롤러에서 나는 액세스 할 수있는 open_flash_chart기능으로 OpenFlashChart, Line

그러나 /lib모듈 의 클래스에서는 작동하지 않습니다!

어떤 아이디어?


이것은 당신이 도울 수 있기를 바랍니다 stackoverflow.com/questions/17304110/...
S.Yadav

답변:


147

Rails에서 파일을로드하는 방법에는 두 가지가 있습니다.

  • 자동로드 프로세스에 등록되며 파일 이름에 해당하는 상수를 참조합니다. 예를 들어 app/controllers/pages_controller.rbPagesController 가 있고 참조하는 경우 app/controllers/pages_controller.rb자동으로로드됩니다. 이는로드 경로의 사전 설정된 디렉토리 목록에서 발생합니다. 이것은 Rails의 기능이며 일반적인 Ruby로드 프로세스의 일부가 아닙니다.
  • 파일은 명시 적으로 required. 파일이 required 인 경우 Ruby는로드 경로의 전체 경로 목록을 살펴보고 사용자 가 d 파일이 로드 경로에있는 첫 번째 경우를 찾습니다 require. $ LOAD_PATH ($ :의 별칭)를 검사하여 전체로드 경로를 볼 수 있습니다.

lib는로드 경로에 있으므로 두 가지 옵션이 있습니다. 상수와 동일한 이름으로 파일 이름을 지정하면 해당 상수를 참조 할 때 Rails가 자동으로 파일을 선택하거나 명시 적으로 모듈을 요구합니다.

나는 또한 당신이 다른 것에 대해 혼란스러워 할 수 있음을 알았습니다. ApplicationController는 시스템의 루트 개체 가 아닙니다 . 관찰 :

module MyModule
  def im_awesome
    puts "#{self} is so awesome"
  end
end

class ApplicationController < ActionController::Base
  include MyModule
end

class AnotherClass
end

AnotherClass.new.im_awesome
# NoMethodError: undefined method `im_awesome' for #<AnotherClass:0x101208ad0>

모듈을 사용하려는 클래스에 포함시켜야합니다.

class AnotherClass
  include MyModule
end

AnotherClass.new.im_awesome
# AnotherClass is so awesome

물론, 처음에 모듈을 포함 할 수 있으려면 위의 기술 중 하나를 사용하여 사용할 수 있어야합니다.


2
추가하고 싶었습니다. / lib (또는 자동로드 디렉토리 중 하나)에있는 모듈 중 하나가 이미 정의되어있는 경우; 예를 들어 ActiveRecord 또는 String을 오버로드하면 명시 적으로 요구해야합니다. 그렇지 않으면로드되지 않습니다
Mike

1
이상하게도 'ga_client'를 미리 요구하지 않는 한 초기화되지 않은 상수 GaClient (NameError)가 발생합니다 (클래스는 lib / ga_client.rb에 정의되어 있음). 자동로드 이름 지정 체계에 대한 문서가 있습니까?
mkirk 2011

87

Rails 3에서 / lib 모듈은 자동으로로드되지 않습니다.

그 이유는 다음과 같습니다.

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

config / application.rb 내부에 주석이 있습니다.

이 줄의 주석 처리를 제거하거나 (나에게 더 잘 작동 함)이 주석을 남겨두고 (나중 참조를 위해) 다음 두 줄을 추가 할 수 있습니다.

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

이것은 배열의 ../lib경로를 복제 합니다 ApplicationName::Application.config.autoload_paths.
jibiel

1
@jibiel 그래서 여기서 해상도는 무엇입니까?
ylluminate 2012

4
후자의 옵션이 더 나은 이유는 무엇입니까? 또한 기본값이 변경된 이유는 ... 많은 사람들이 해결 방법을 찾았음에도 불구하고 이유가있을 것입니다.
ckarbass

@ylluminate 그래서 싱글 config.autoload_paths += Dir["#{config.root}/lib/**/"]이면 충분합니다. @ckarbass 두 번째 줄은 유틸리티를 하위 폴더 로 구성 할 수있는 자유를 제공 하므로 네임 스페이스로 모듈을 멋지게 꾸밀 수 있습니다 . 그게 다야. 기본값이 변경된 이유 는 다음 과 같습니다 . 결코 늦지 않는 것보다 낫다 :)
jibiel 2014 년

이것은 나에게 약간 지저분 해 보입니다. 이것은 불필요하게 자동로드 레이크 작업이 아닐까요?
Dennis

22

나를 위해 일한 것은 config.autoload_paths (나는 Rails 3.1.3에 있습니다)의 주석 처리를 제거하는 것 외에도 다음과 같은 이니셜 라이저를 만드는 것이 었습니다.

#config/initializers/myapp_init.rb
require 'my_module'    
include MyModule

이런 식으로 어디서나 클래스 메서드 Model.mymodule_method또는 인스턴스 메서드 로 mymodule 메서드 호출 할 수 있습니다.mymodel.mymodule_method

아마도 일부 전문가가 이것의 의미를 설명 할 수 있습니다. 지금까지는 자신의 책임하에 사용하십시오.

편집 : 나중에 더 나은 방법은 다음과 같습니다.

다음과 같은 이니셜 라이저를 만듭니다.

#config/initializers/myapp_init.rb
require ‘my_module’

필요한 곳에 다음과 같이 모듈을 포함합니다.

1) "Class Methods"로 사용하려면 "extend"를 사용하십시오.

class Myclass < ActiveRecord::Base
   extend MyModule
   def self.method1
      Myclass.my_module_method
   end
end

2) "인스턴스 메소드"로 사용하려면 클래스 정의에 포함하십시오.

class Myclass < ActiveRecord::Base
include MyModule
   def method1
      self.my_module_method 
   end
end

3) 먼저 필요한로드 경로 include MyModule의 파일 my_module.rb을 참조하십시오.


3
lib폴더에 모듈을 만들었 으므로 파일에 추가 config.autoload_paths += %W(#{config.root}/lib)했습니다 config/application.rb. 그 후 나는 config/initializers/myapp_init.rb파일 추가에 대한 귀하의 제안을 따랐으며 내용입니다. 모든 좋은. 고마워요 :)
SMMousavi

비록 require저와 자동 로딩을위한 작품, (정의되지 않은 모듈 방식)하지 않는 이 댓글 말한다 당신은 사용하지 말아야합니다require .
Dennis

3

lib/my_module.rb모델 및 컨트롤러에서 모듈을 사용하려면 :

에서 config/application.rb:

config.watchable_dirs['lib'] = [:rb]

모델에서 (컨트롤러에 대한 유사한 아이디어) :

require_dependency 'my_module'

class MyModel < ActiveRecord::Base
  include MyModule

  MyModule.some_method
end

이 방법은 http://hakunin.com/rails3-load-paths 에 자세히 설명되어 있습니다 .


0

응용 프로그램 초기화시 lib 디렉토리 아래에 파일을 명시 적으로로드하려는 경우 일 수 있습니다.
내 config / application.rb에는 다음과 같은 항목
config.autoload_paths += %W(#{config.root}/lib)

이 있습니다. 또한 모듈 이름 / 계층이 파일에있는 것과 같지 않거나 파일의 위치 / 이름이 해당 계층과 동일하지 않은 경우 일 수 있으므로 자동로드 그 파일의 또한 불가능합니다. 따라서 config / application.rb 하단에 항목을 추가하면
require "./lib/file_name_without_extention
정상적으로 작동했습니다.

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