Bri*_*ong 8 ruby ruby-on-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 >
Run Code Online (Sandbox Code Playgroud)
lul*_*ala 11
对于想要在类级别lib或模型中使用某些自定义帮助程序的人来说,有时包含所有帮助程序是不值得的.而是直接调用它:
class MyClass
def test
::ApplicationController.helpers.number_to_human_size(42)
end
end
Run Code Online (Sandbox Code Playgroud)
(摘自http://makandracards.com/makandra/1307-how-to-use-helper-methods-inside-a-model)
我遇到了同样的问题.这就是我解决它的方式,
helper = Object.new.extend(ActionView::Helpers::NumberHelper)
helper.number_to_human_size(1000000)
Run Code Online (Sandbox Code Playgroud)
感谢RailsForum.
没有看到你的帮助程序代码很难说,但是include会将该模块中的所有方法插入到你所包含的类的实例中.extend用于将方法引入类中.因此,如果你只是在NumberHelper中定义了方法,那么这些方法将放在MyClass的所有实例上,而不是类.
许多Rails扩展的工作方式是使用已整合到ActiveSupport :: Concern中的技术.这是一个很好的概述.
从本质上讲,在模块中扩展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"
Run Code Online (Sandbox Code Playgroud)
之前我已经使用过这个来做类似于在ClassMethods中定义bar函数的事情,然后通过定义一个只调用this.class.bar的同名的bar方法使它可用于实例,使它可以从两者中调用.ActiveSupport :: Concern还有很多其他有用的东西,比如允许你定义在包含模块时回调的块.
现在,这发生在这里特别是因为你是include你的助手,这可能表明这个功能比助手更通用 - 助手只会自动包含在视图中,因为它们只是为了帮助查看.如果你想在一个视图中使用你的助手,你可以使用helper_method你的类中的宏来使你的视图可以看到该方法,或者更好的是,如上所述制作一个模块,而不是将其视为帮助者,而是使用include将它混合到你想要使用它的类中.我想我会走那条路 - 没有什么说你不能include在NumberHelper中创建一个HumanReadableNumber模块,以便在你的视图中轻松使用它.