模型中不能包含模块

时间:2011-03-09 10:24:18

标签: ruby-on-rails ruby ruby-on-rails-3

我正在使用

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'

我做错了什么?

3 个答案:

答案 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

这样,alivedead将在类本身上提供,而不是其实例。

答案 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