Search code examples
rubyruby-on-rails-5rspec-rails

Include Module Method in Nested Model Class


In several places in my codebase, I have a hard-coded integer that I have to pull into a method so it can be changed in one place. I have created a module in lib/due_date.rb and added a method:

module DueDate
  def due_date(days=10)
    days
  end
end

I've included it in some model class and it works fine (these classes are not nested). The issue I'm having is including it in nested model classes. For instance, when the model class looks like this:

module A
  module B
    class C
      include DueDate
    end
  end
end

I get the following error:

undefined local variable or method 'due_date' for #<Class:......>

In class C, I'm first trying to assign it to a constant that's used in other places in the class:

THRESHOLD = due_date

The second place I'm trying to use it is in a scope with a where clause:

scope :range -> {
  .where("due_date <= NOW() + INTERNAL '#{due_date} days'")
}

How can I include my DueDate module in the nested classes so I can use the due_date method in these two ways?

UPDATE: including the module in the class works fine, so it's how I'm trying to use the method that isn't working.


Solution

  • If you want the method to be available as an instance method, then everything you're doing is correct.

    However, from your examples it looks like you're trying to use it as a class method instead. To achieve that, you need to extend the module rather than include it.

    module A
      module B
        class C
          extend DueDate
    
          THRESHOLD = due_date
        end
      end
    end
    
    A::B::C::THRESHOLD #=> 10
    A::B::C.due_date #=> 10