我正在使用
Ruby version 1.8.7
Rails version 3.0.3
我的rails应用程序的每个模型都有一个名为alive的方法:
def alive
where('deleter is null')
end
我不想在每个模型中复制此代码,所以我制作了一个/lib/life_control.rb
module LifeControl
def alive
where('deleter is null')
end
def dead
where('deleter is not null')
end
end
在我的模型中(例如client.rb)我写道:
class Client < ActiveRecord::Base
include LifeControl
end
在我的config / enviroment.rb中我写了这一行:
require 'lib/life_control'
但现在我得到一个no方法错误:
NoMethodError in
ClientsController#index
undefined method `alive' for
#<Class:0x10339e938>
app/controllers/clients_controller.rb:10:in
`index'
我做错了什么?
答案 0 :(得分:23)
include
会将这些方法视为实例方法,而不是类方法。你想要做的是:
module LifeControl
module ClassMethods
def alive
where('deleter is null')
end
def dead
where('deleter is not null')
end
end
def self.included(receiver)
receiver.extend ClassMethods
end
end
这样,alive
和dead
将在类本身上提供,而不是其实例。
答案 1 :(得分:5)
我知道这是一个非常古老的问题,接受的答案对我有用,但这意味着我必须重新编写大量代码,因为我必须将模块更改为嵌套模块。
这对我的情况有所帮助,应该适用于今天的大多数应用程序。(不确定它是否适用于问题中的ruby / rails版本)
而不是include
使用extend
因此,根据问题,示例代码如下所示:
class Client < ActiveRecord::Base
extend LifeControl
end
答案 2 :(得分:-1)
只需将此行放在application.rb文件
中config.autoload_paths += Dir["#{config.root}/lib/**/"]
编辑:
这条线对我来说很好。 我想再提一个建议,ruby 1.8.x与rails 3.x不兼容。 所以只需更新你的ruby版本1.9.2
以下是我的POC
In lib folder: lib/test_lib.rb module TestLib def print_sm puts "Hello World in Lib Directory" end end In model file: include TestLib def test_method print_sm end And In application.rb config.autoload_paths += Dir["#{config.root}/lib/**/"] Now you can call test_method like this in controller: ModelName.new.test_method #####Hello World in Lib Directory