Невозможно включить модуль в модель
Я использую
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