2011-03-09 80 views
10

我使用不能包含模块模型

Ruby version    1.8.7 
Rails version    3.0.3 

我有一个在我的Rails应用程序的每一个模型叫活着方法:

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' 

,但现在我得到一个无方法错误:

NoMethodError in 
ClientsController#index 

undefined method `alive' for 
#<Class:0x10339e938> 

app/controllers/clients_controller.rb:10:in 
`index' 

我究竟做错了什么?

+0

你叫的类或实例级别的方法? – pythonandchips 2011-03-09 12:53:26

+0

在课堂上的水平 – w1ng 2011-03-09 14:35:37

回答

20

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 

这样,alivedead将可在类本身,而不是它们的实例。

+0

谢谢!那解决了我的问题 – w1ng 2011-03-10 07:01:14

+0

我一直在疯狂搜索,但没有找到好的答案,直到我得到您的答复。非常感谢。 – 2012-03-08 00:44:49

+2

如果你扩展而不是包含你的模块方法将被分配给类。 – 2013-08-23 20:50:06

-1

只是把这个线在application.rb中文件

 
config.autoload_paths += Dir["#{config.root}/lib/**/"] 

编辑:

此行是为我工作的罚款。 我想提出一件事,ruby 1.8.x与rails 3.x不兼容。 所以只要更新您的红宝石版本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 

+0

我把行放在application.rb中,但是我仍然得到错误 – w1ng 2011-03-09 10:51:28

+0

你重新启动了你的应用程序吗? – 2011-03-09 11:18:39

+0

是的,我重新启动应用程序 – w1ng 2011-03-09 11:47:26

2

我知道这是一个很老的问题,接受的答案确实对我有用,但这意味着我不得不重写很多代码,因为我必须将模块更改为嵌套模块。

这是我的情况帮助我,并应与今天的大多数应用程序的工作。(不知道它会在红宝石工作中的问题/导轨版本)

而不是做include使用extend

所以按这个问题,示例代码如下所示:

class Client < ActiveRecord::Base 
    extend LifeControl 
end