Невозможно включить модуль в модель

Я использую

Ruby version              1.8.7
Rails version             3.0.3

У меня есть метод, который называется live в каждой модели моего приложения 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'

что я делаю неправильно?

Ответ 1

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 будут доступны в самом классе, а не в таких случаях.

Ответ 2

Я знаю, что это довольно старый вопрос, принятый ответ действительно сработал у меня, но это означало, что мне пришлось переписать много кода, потому что мне нужно изменить модуль на вложенный.

Это помогло мне в моей ситуации и должно работать с большинством приложений сегодня (не уверен, что это будет работать в версии ruby ​​/rails в вопросе)

вместо include использовать extend

Итак, в соответствии с вопросом, пример кода будет выглядеть так:

class Client < ActiveRecord::Base
  extend LifeControl   
end

Ответ 3

Просто поместите эту строку в файл application.rb

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

Отредактировано:

Эта строка отлично работает для меня. Я хочу предложить еще одну вещь, ruby ​​1.8.x не совместим с рельсами 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