open_flash_chart
プラグインのカスタムラッパーを書いています。に配置さ/lib
れ、モジュールとしてにロードされますApplicationController
。
ただし、クラス階層またはsmthの問題があります。
どのコントローラーからでも、などのopen_flash_chart
機能にアクセスできますOpenFlashChart
Line
ただし、/lib
モジュール内のクラスでは機能しません。
何か案は?
回答:
Railsにファイルをロードする方法は2つあります。
app/controllers/pages_controller.rb
PagesControllerを持っていて参照している場合、app/controllers/pages_controller.rb
は自動的に読み込まれます。これは、ロードパス内のディレクトリのプリセットリストで発生します。これはRailsの機能であり、通常のRubyロードプロセスの一部ではありません。require
dです。ファイルがrequire
dの場合、Rubyはロードパス内のパスのリスト全体を調べ、dファイルがロードパス内にある最初のケースを見つけrequire
ます。$ LOAD_PATH($:のエイリアス)を調べると、ロードパス全体を確認できます。以来lib
、あなたのロードパスにある、2つのオプションがあります。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内にコメントがあります。
この行のコメントを解除するか、(私にとってはさらにうまく機能しました)、これをコメントのままにして(将来の参照用に)、次の2行を追加してみてください。
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 2行目では、ユーティリティをサブフォルダに整理して、モジュールを名前空間で自由に整理できます。それはほとんどそれです。そして、これがデフォルトが変更された理由です。決して遅くなるよりはましだ:)
config.autoload_pathsのコメントを外す(私はRails 3.1.3を使用しています)以外に、私にとってうまくいったのは、次のような初期化子を作成することでした。
#config/initializers/myapp_init.rb
require 'my_module'
include MyModule
このようにして、mymoduleメソッドをどこからでも、クラスメソッドModel.mymodule_method
またはインスタンスメソッドとして呼び出すことができます。mymodel.mymodule_method
たぶん、一部の専門家はこれの意味を説明するかもしれません。今では、自己責任で使用してください。
編集:その後、私はより良いアプローチは次のようになると思います:
次のような初期化子を作成します。
#config/initializers/myapp_init.rb
require ‘my_module’
次のように、必要に応じてモジュールを含めます。
1)「クラスメソッド」として使用する場合は、「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
正常に機能しました。