简体   繁体   English

不能在模型中包含模块

[英]Cannot include module in model

I'm using我正在使用

Ruby version              1.8.7
Rails version             3.0.3

I have a method called alive in every model of my rails app:我在 Rails 应用程序的每个模型中都有一个名为活着的方法:

  def alive
    where('deleter is null')  
  end   

I don't want to copy this code in every model so I made a /lib/life_control.rb我不想在每个模型中复制这段代码,所以我做了一个 /lib/life_control.rb

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

  def dead
    where('deleter is not null')  
  end    
end

and in my model (for example client.rb) I wrote:在我的模型(例如 client.rb)中,我写道:

class Client < ActiveRecord::Base
  include LifeControl   
end

and in my config/enviroment.rb I wrote this line:在我的 config/enviroment.rb 我写了这一行:

require 'lib/life_control'

but now I get a no method error:但现在我得到一个无方法错误:

NoMethodError in
ClientsController#index

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

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

what am I doing wrong?我究竟做错了什么?

include will treat those methods as instance methods, not class methods. include会将这些方法视为实例方法,而不是类方法。 What you want to do is this:你想要做的是:

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

This way, alive and dead will be available on the class itself, not instances thereof.这样, alivedead将在类本身上可用,而不是在其实例上可用。

I'm aware this is a pretty old question, the accepted answer did work for me, but that meant me having to re-write a lot of code because i have to change the module to a nested one.我知道这是一个很老的问题,接受的答案确实对我有用,但这意味着我必须重新编写大量代码,因为我必须将模块更改为嵌套模块。

This is what helped me with my situation and should work with most of today's applications.(not sure if it'll work in the ruby/rails version in the question)这对我的情况有帮助,并且应该适用于当今的大多数应用程序。(不确定它是否适用于问题中的 ruby​​/rails 版本)

instead of doing include use extend而不是include使用extend

So as per the question, the sample code would look like:因此,根据问题,示例代码如下所示:

class Client < ActiveRecord::Base
  extend LifeControl   
end

Just put this line in application.rb file只需将此行放在 application.rb 文件中

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

Edited:编辑:

This line is working fine for me.这条线对我来说很好用。 I want to suggest one more thing, ruby 1.8.x is not compatible with rails 3.x.我想再提出一件事,ruby 1.8.x 与 rails 3.x 不兼容。 So just update your ruby for version 1.9.2所以只需更新您的 ruby​​ 版本 1.9.2

Following is my POC以下是我的 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM