模型中不能包含模块

w1n*_*1ng 12 ruby ruby-on-rails ruby-on-rails-3

我正在使用

Ruby version              1.8.7
Rails version             3.0.3
Run Code Online (Sandbox Code Playgroud)

我的rails应用程序的每个模型都有一个名为alive的方法:

  def alive
    where('deleter is null')  
  end   
Run Code Online (Sandbox Code Playgroud)

我不想在每个模型中复制此代码,因此我创建了一个/lib/life_control.rb

module LifeControl    
  def alive
    where('deleter is null')  
  end   

  def dead
    where('deleter is not null')  
  end    
end
Run Code Online (Sandbox Code Playgroud)

在我的模型中(例如client.rb)我写道:

class Client < ActiveRecord::Base
  include LifeControl   
end
Run Code Online (Sandbox Code Playgroud)

在我的config/enviroment.rb中我写了这一行:

require 'lib/life_control'
Run Code Online (Sandbox Code Playgroud)

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

NoMethodError in
ClientsController#index

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

app/controllers/clients_controller.rb:10:in
`index'
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

Dan*_*ail 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
Run Code Online (Sandbox Code Playgroud)

这样,alive并且dead将在类本身上提供,而不是其实例.

  • 如果扩展而不是包含您的模块方法将被分配给该类. (4认同)

Alf*_*fie 6

我知道这是一个非常古老的问题,接受的答案对我有用,但这意味着我必须重新编写大量代码,因为我必须将模块更改为嵌套模块.

这对我的情况有所帮助,应该适用于今天的大部分应用程序.(不确定它是否适用于问题中的ruby/rails版本)

而不是include使用extend

因此,根据问题,示例代码如下所示:

class Client < ActiveRecord::Base
  extend LifeControl   
end
Run Code Online (Sandbox Code Playgroud)