2009-06-17 10 views
0

私はvendor/{engine}/app/helpers/application_helper.rbにこのコードを持っている:Rubyのモジュールをオーバーライドしますか?

app/helpers/application_helper.rb
module ApplicationHelper 
    def application_title() 
    "Foo" 
    end 

    def other_method() 
    # ... 
    end 
end 

そして、この:

module ApplicationHelper 
    def application_title() 
    "Bar" 
    end 
end 

私のアプリからapplication_title()を呼び出すときに、予想通り、私は「バー」を得るが、私のアプリケーションはother_method()を見ることができません。これを修正するにはどうすればApplicationHelperを変更できますか?

+0

うーん...なぜそうなるのか分かりません。最初のApplicationHelperがあなたのプロジェクトに全く含まれていることは確かですか? 'application_title'を削除すると、" Foo "が得られますか? –

+0

。ヘルパーが実際にあなたのアプリに含まれていると確信していますか? – cpjolicoeur

+0

application_title()メソッドを削除すると、application_title()が定義されていないというエラーが表示されます。しかし、私がモジュール全体を削除すると、私は "Foo"を取得します。 –

答えて

0

私の問題は、エンジンのヘルパーがメインアプリケーションのものを上回ることを期待しているということです。私は、これが持ち込まれていなかったエンジンのプラグインではなく、Railsの2.3この機能で働いていたと信じています。から

http://rails-engines.org/news/2009/02/02/engines-in-rails-2-3/

コード " のいずれかを実行しようとしません

のRails 2.3を混合「コードミキシング」エンジン プラグインがします。ない ノウハウであなたのそれらのために、これはあなたのアプリケーションが アプリケーションにプラグインから ファイル全体をコピーすることなく、コントローラまたは ヘルパーで つのメソッドをオーバーライドすることができます機能 です。

私は確かに言うことはできませんが、私は、この機能は今まで レール自体にそれを作るだろう、と正直に言うと、私はそれはおそらく良いことだと思う を疑います。 コード混合メカニズムは ですが、他の方法で の実装をオーバーライドする方法があります。より一般的には Rubyishであり、より少ない魔法です。私は しようとすぐにここにいくつかの例を投稿します。

これが役に立ちます。

+0

エンジンの動作例については、http://agilewebdevelopment.com/plugins/datebocksengineも参照してください。 –

+0

具体的には、ステップ5はエンジンからのヘルパーをプロジェクトヘルパーに含めることを示します。 –

+0

D'oh。まあ、それはバカです。私は本当にこの機能を使うことができればと思っていました。物事をするよりスマートな方法がありますか? –

0

これはRailsの問題だとは言えませんが、私の推測ではそれほど目立たないことです。最後の「修正」は、Railsアプリケーションの場合には簡単に適用できない場合があります。

まず、ディレクトリリスト:

> ls -R 
.: 
bar_then_foo.rb bar_then_foo2.rb foo_then_bar.rb lib_foo lib_fubar 

./lib_foo: 
helper.rb 

./lib_fubar: 
helper.rb 

ヘルパーモジュール:

> cat lib_foo/helper.rb 
module Helper 
    def foo 
    puts "foo" 
    end 

    def bar 
    puts "bar" 
    end 
end 

> cat lib_fubar/helper.rb 
module Helper 
    def foo 
    puts "foo-bar" 
    end 
end 

Rubyコード:

> cat bar_then_foo.rb 
$LOAD_PATH.unshift File.dirname(__FILE__) + '/lib_fubar' 
$LOAD_PATH.unshift File.dirname(__FILE__) + '/lib_foo' 

require 'helper' 

class FoobieDoo 
    include Helper 
end 

f = FoobieDoo.new 
f.foo 
f.bar 

> cat foo_then_bar.rb 
$LOAD_PATH.unshift File.dirname(__FILE__) + '/lib_foo' 
$LOAD_PATH.unshift File.dirname(__FILE__) + '/lib_fubar' 

require 'helper' 

class FoobieDoo 
    include Helper 
end 

f = FoobieDoo.new 
f.foo 
f.bar 

そして、いくつかの出力:

> ruby bar_then_foo.rb 
foo 
bar 

> ruby foo_then_bar.rb 
foo-bar 
foo_then_bar.rb:12: undefined method 'bar' for #<FoobieDoo:0x1042e93c> (NoMethodError) 

したがって、Rubyは最後から$ LOAD_PATHを検索し、一致するものを見つけるとすぐに停止します。

> cat bar_then_foo2.rb 
$LOAD_PATH.unshift File.dirname(__FILE__) + '/lib_fubar' 
$LOAD_PATH.unshift File.dirname(__FILE__) + '/lib_foo' 

require 'helper' 
load "lib_fubar/helper.rb" 

class FoobieDoo 
    include Helper 
end 

f = FoobieDoo.new 
f.foo 
f.bar 

> ruby bar_then_foo2.rb 
foo-bar 
bar 

望ましい結果:

はのは、何か他のものを試してみましょうか?

おそらくapp/helpers/application_helper.rbを変更して、LOAD_PATHの他のapplication_helper.rbファイルを検索してロードすることはできますか?

関連する問題