Gandalf StormCrow
Gandalf StormCrow

Reputation: 26192

Reusing code ruby on rails

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

Answers (5)

johansenja
johansenja

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

Mischa
Mischa

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

zwippie
zwippie

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

deepflame
deepflame

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

Mihai8
Mihai8

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

Related Questions