open_flash_chart
플러그인에 대한 사용자 정의 래퍼를 작성 중 입니다. 에 배치 /lib
되고 ApplicationController
.
그러나 클래스 계층 구조 또는 smth 문제가 있습니다.
어떤 컨트롤러에서 나는 액세스 할 수있는 open_flash_chart
기능으로 OpenFlashChart
, Line
등
그러나 /lib
모듈 의 클래스에서는 작동하지 않습니다!
어떤 아이디어?
open_flash_chart
플러그인에 대한 사용자 정의 래퍼를 작성 중 입니다. 에 배치 /lib
되고 ApplicationController
.
그러나 클래스 계층 구조 또는 smth 문제가 있습니다.
어떤 컨트롤러에서 나는 액세스 할 수있는 open_flash_chart
기능으로 OpenFlashChart
, Line
등
그러나 /lib
모듈 의 클래스에서는 작동하지 않습니다!
어떤 아이디어?
답변:
Rails에서 파일을로드하는 방법에는 두 가지가 있습니다.
app/controllers/pages_controller.rb
PagesController 가 있고 참조하는 경우 app/controllers/pages_controller.rb
자동으로로드됩니다. 이는로드 경로의 사전 설정된 디렉토리 목록에서 발생합니다. 이것은 Rails의 기능이며 일반적인 Ruby로드 프로세스의 일부가 아닙니다.require
d. 파일이 require
d 인 경우 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/**/"]
../lib
경로를 복제 합니다 ApplicationName::Application.config.autoload_paths
.
config.autoload_paths += Dir["#{config.root}/lib/**/"]
이면 충분합니다. @ckarbass 두 번째 줄은 유틸리티를 하위 폴더 로 구성 할 수있는 자유를 제공 하므로 네임 스페이스로 모듈을 멋지게 꾸밀 수 있습니다 . 그게 다야. 기본값이 변경된 이유 는 다음 과 같습니다 . 결코 늦지 않는 것보다 낫다 :)
나를 위해 일한 것은 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
폴더에 모듈을 만들었 으므로 파일에 추가 config.autoload_paths += %W(#{config.root}/lib)
했습니다 config/application.rb
. 그 후 나는 config/initializers/myapp_init.rb
파일 추가에 대한 귀하의 제안을 따랐으며 내용입니다. 모든 좋은. 고마워요 :)
require
저와 자동 로딩을위한 작품, (정의되지 않은 모듈 방식)하지 않는 이 댓글 말한다 당신은 사용하지 말아야합니다require
.
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
정상적으로 작동했습니다.