2011-06-09 242 views
8

有人知道为什么包含的方法在类方法中不起作用吗?Rails在类方法中使用包含的帮助程序

class MyClass 
    include ActionView::Helpers::NumberHelper 

    def test 
    puts "Uploading #{number_to_human_size 123}" 
    end 

    def self.test 
    puts "Uploading #{number_to_human_size 123}" 
    end 
end 


ree-1.8.7-2011.03 :004 > MyClass.new.test 
Uploading 123 Bytes 
=> nil 
ree-1.8.7-2011.03 :005 > MyClass.test 
NoMethodError: undefined method `number_to_human_size' for MyClass:Class 
    from /path/to/my/code.rb:9:in `test' 
    from (irb):5 
ree-1.8.7-2011.03 :006 > 

回答

5

很难说没有看到你的助手代码,但include将插入所有这些模块中的方法分为情况下,你包括到类的extend用于将方法带入。因此,如果你只有在NumberHelper中定义的方法,这些方法将被放到MyClass的所有实例上,但不放在类中。

很多Rails扩展工作的方式是使用已整合到ActiveSupport :: Concern中的技术。 Here是一个很好的概述。

从本质上讲,扩展模块中的ActiveSupport :: Concern将允许您在称为ClassMethods和InstanceMethods的子模块中指定要将哪些函数添加到包含模块的类和实例中。例如:

module Foo 
    extend ActiveSupport::Concern 
    module ClassMethods 
     def bar 
      puts "I'm a Bar!" 
     end 
    end 
    module InstanceMethods 
     def baz 
      puts "I'm a Baz!" 
     end 
    end 
end 

class Quox 
    include Foo 
end 

Quox.bar 
=> "I'm a Bar" 
Quox.new.baz 
=> "I'm a Baz" 

我用这个之前做的事情一样定义ClassMethods酒吧功能,那么也将其提供给实例通过定义一个只是调用this.class同名的杆法。酒吧,使它可以从两者中调用。 ActiveSupport :: Concern还提供了许多其他有用的功能,例如允许您定义在包含模块时被回调的块。现在

,这是专门在这里发生的事情,因为你是include荷兰国际集团的帮助,这可能表明,这个功能是更通用比帮手 - 佣工只自动包含在意见,因为它们只以帮助观点。如果你想在视图中使用你的助手,你可以在你的类中使用helper_method宏来让你的视图看到该方法,或者,甚至更好的方法是像上面那样创建一个模块,而不是将其视为助手,而是使用包括混合它到你想要使用它的类中。我想我会走这条路 - 没有什么说你不能在HumanHadperNumber模块中创建HumanReadableNumber模块,并且它在NumberHelper中使它易于在视图中使用。

6

我面临同样的问题。以下是我如何解决它,

helper = Object.new.extend(ActionView::Helpers::NumberHelper) 
helper.number_to_human_size(1000000) 

感谢RailsForum

+0

非常直接的解决方案..谢谢:) – SSR 2015-03-12 10:24:15

+0

如果帮你请标明正确:) – 2015-03-12 17:18:33

+0

这不是我的问题,所以我不能接受你的答案为可接受的。 :( – SSR 2015-03-13 04:30:11