简体   繁体   English

在rails上重用代码ruby

[英]Reusing code ruby on rails

I've got a module in my project in lib/. 我在lib /中的项目中有一个模块。 it's content is like this : 它的内容是这样的:

module Search
  module Score

    def get_score
      return 'something'
    end

  end    
end

This Search has many different modules I need to use Score. 此搜索有许多不同的模块,我需要使用分数。 I realize I need to add require in my model (I'm trying to use this from model). 我意识到我需要在我的模型中添加require(我试图从模型中使用它)。 So here is my code (model) : 所以这是我的代码(模型):

require 'search'

class User < ActiveRecord::Base

  def get_user_score
    #tried this :
    p Search::Score.get_score #error
    #this as well
    score_instance = Score.new #error
    score = Search::Score.get_score # error undefined method `get_score'
  end

end

So how do I reuse the code I have in other class (module)? 那么如何重用我在其他类(模块)中的代码呢?

To get it working you can either mix the module into your class: 要使其正常工作,您可以将模块混合到您的班级中:

require 'search'

class User < ActiveRecord::Base
  include Search::Score

  def get_user_score
    p get_score # => "something"
  end
end

Or you can define the method inside your module similar to class methods: 或者您可以在类模块中定义方法,类似于类方法:

module Search
  module Score
    def self.get_score
      return 'something'
    end
  end    
end

If you do that, you can call get_score like expected: 如果你这样做,你可以像预期的那样调用get_score

require 'search'

class User < ActiveRecord::Base
  def get_user_score
    p Search::Score.get_score # => "something"
  end
end

See this tutorial for a more in depth explanation about modules in Ruby. 有关Ruby中模块的更深入说明,请参阅本教程

Search::Score is a module and not a class, so Score.new will not work. Search::Score是一个模块,而不是一个类,所以Score.new不起作用。

You can try to change the signature of the get_score function to self.get_score . 您可以尝试将get_score函数的签名更改为self.get_score

"Modules are crippled classes" “模块是残废的类”

Modules are like crippled classes in Ruby. 模块就像Ruby中的残缺类。 If you look into the inheritance chain you see that a Class actually inherits from Module. 如果查看继承链,您会发现Class实际上是从Module继承的。

Module cannot be instanciated. 模块无法实现。 So the call to .new is not working. 所以对.new的调用不起作用。

What you CAN do however is to specify your method as a 'class' method (I know I said it is not a class...) 但你可以做的是将你的方法指定为“类”方法(我知道我说它不是一个类......)

So you would add a self in front like this: 所以你会像这样在前面添加一个自我:

module Search
  module Score

    def self.get_score
      return 'something'
    end

  end    
end

Then you can call this method as a class method like you tried in your code example 然后,您可以像在代码示例中尝试的那样将此方法称为类方法

In addition to def self.get_score in the above answers, there is also extend self , like so: 除了在上面的答案中def self.get_score之外,还有extend self ,如下所示:

module Search
  module Score
    extend self

    def get_score
      return 'something'
    end
  end    
end

and module_function : module_function

module Search
  module Score
    module_function

    def get_score
      return 'something'
    end
  end    
end

The latter is actually the preferred method in RuboCop (source) , though in practice I personally have not seen it so often. 后者实际上是RuboCop (源代码)中的首选方法,尽管在实践中我个人并没有经常看到它。

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

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