0

I've got a module in my project in 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). 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)?

0

5 Answers 5

2

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:

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.

Sign up to request clarification or add additional context in comments.

Comments

0

First, see "Best Practices for reusing code between controllers in Ruby on Rails".

About reuse code as a module, take a look at "Rethinking code reuse with Modularity for Ruby".

Comments

0

"Modules are crippled classes"

Modules are like crippled classes in Ruby. If you look into the inheritance chain you see that a Class actually inherits from Module.

Module cannot be instanciated. So the call to .new is not working.

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

1 Comment

I wouldn't call them anything like a crippled class. They are a very powerful feature with a great reason for existing and are key to what makes Ruby a cool language. Comparable and Enumerable are powerful modules that demonstrate what is good about modules.
0

Search::Score is a module and not a class, so Score.new will not work.

You can try to change the signature of the get_score function to self.get_score.

Comments

0

In addition to def self.get_score in the above answers, there is also extend self, like so:

module Search
  module Score
    extend self

    def get_score
      return 'something'
    end
  end    
end

and 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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.