Reputation: 26192
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)?
Upvotes: 0
Views: 2257
Reputation: 678
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.
Upvotes: 0
Reputation: 43298
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.
Upvotes: 2
Reputation: 15515
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
.
Upvotes: 0
Reputation: 928
"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
Upvotes: 0
Reputation: 3147
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".
Upvotes: 0