web-dev-qa-db-ja.com

Rails / libモジュールと

open_flash_chartプラグインのカスタムラッパーを作成しています。 /libに配置され、ApplicationControllerにモジュールとしてロードします。

ただし、クラス階層またはsmthの問題があります。

任意のコントローラーから、OpenFlashChartLineなどとしてopen_flash_chart関数にアクセスできます。

ただし、/libモジュールのクラスでは機能しません。

何か案は?

81
Mantas

ファイルをRailsにロードする方法は2つあります。

  • 自動ロードプロセスに登録され、ファイル名に対応する定数を参照します。たとえば、app/controllers/pages_controller.rbおよび参照PagesController、app/controllers/pages_controller.rbは自動的にロードされます。これは、ロードパス内のディレクトリのプリセットリストに対して発生します。これはRailsの機能であり、通常のRuby=ロードプロセスの一部ではありません。
  • ファイルは明示的にrequiredです。ファイルがrequiredの場合、Rubyはロードパス内のパスのリスト全体を調べ、requiredが含まれる最初のケースを見つけます。ロードパス:$ LOAD_PATH($:のエイリアス)を調べると、ロードパス全体を確認できます。

libはロードパスにあるため、2つのオプションがあります。ファイルに定数と同じ名前を付けるか、またはRailsは、問題の定数、または明示的にモジュールが必要です。

また、別のことについて混乱している可能性があることにも気づきました。 ApplicationControllerはnotシステム内のルートオブジェクトです。観察する:

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

もちろん、最初にモジュールを含めることができるようにするには、モジュールを使用可能にする必要があります(上記の手法のいずれかを使用)。

146
Yehuda Katz

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

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最初に必要なロードパス

21

モジュールを使用するには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 で説明しています。

2
Dennis

アプリケーションの初期化時にlibディレクトリの下にファイルを明示的にロードしたい場合があります。
config/application.rbに、次のエントリがあります。
config.autoload_paths += %W(#{config.root}/lib)

これは、モジュール名/階層がファイル内にあるのと同じではない場合や、ファイルの場所/名前がその階層と同じではない場合もあるため、そのファイルの自動ロードもできません。したがって、config/application.rbの下部にエントリを追加すると、
require "./lib/file_name_without_extention
それはうまくいきました。

0