在Ruby中覆盖模块?

时间:2009-06-17 17:07:17

标签: ruby-on-rails ruby

我在vendor/{engine}/app/helpers/application_helper.rb中有这段代码:

module ApplicationHelper
  def application_title()
    "Foo"
  end

  def other_method()
    # ...
  end
end

这是app/helpers/application_helper.rb

module ApplicationHelper
  def application_title()
    "Bar"
  end
end

从我的应用中调用application_title()时,我按预期获得“Bar”,但我的应用程序看不到other_method()。如何修改ApplicationHelper以解决此问题?

2 个答案:

答案 0 :(得分: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文件并加载它们?

答案 1 :(得分:0)

我认为问题在于您希望引擎中的帮助程序覆盖主应用程序中的帮助程序。我相信这在Engines插件中有效,但在Rails 2.3中没有引入这个功能。

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

  

代码混合

     

Rails 2.3不会尝试执行任何操作   引擎的'代码混合'   插件呢。对于那些不在你身边的人   知道,这是功能   让你的应用程序覆盖一个   控制器中的单个方法或   帮手,无需复制   整个文件从插件进入你的   应用

     

我不能肯定地说,但我怀疑   这个功能将永远成功   Rails本身,说实话,我   认为这可能是一件好事。   虽然代码混合机制是   相当整洁,还有其他方法   压倒执行   更典型的方法   Rubyish,并且涉及较少的魔法。生病   试着尽快发布一些例子。

希望这有帮助。