[ruby-on-rails] Rails / lib 모듈 및

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

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

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

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

어떤 아이디어?



답변

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

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


답변

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/**/"]


답변

나를 위해 일한 것은 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을 참조하십시오.


답변

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 에 자세히 설명되어 있습니다 .


답변

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

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


답변