Не удается включить модуль в модель - PullRequest
12 голосов
/ 09 марта 2011

Я использую

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

и в моей конфигурации / среде.рб Я написал эту строку:

require 'lib/life_control'

но теперь я получаю сообщение об ошибке метода:

NoMethodError in
ClientsController#index

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

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

что я делаю не так?

Ответы [ 3 ]

23 голосов
/ 10 марта 2011

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

6 голосов
/ 04 сентября 2016

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

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

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

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

class Client < ActiveRecord::Base
  extend LifeControl   
end
0 голосов
/ 09 марта 2011

Просто поместите эту строку в файл 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...