Search code examples
ruby-on-railsrubyactivesupport-concern

ruby: avoid duplicate method in genertors


I'm having trouble to avoid duplicate code in my generators. I have tried to use concerns but without success. Can anyone help me ?

My 3 generators are having the same method called :

# Initialize the generator accepting attributes as arguments  
  def initialize(*args, &block)
    super
    @attributes = []
    model_attributes.each do |attribute|
      @attributes << Rails::Generators::GeneratedAttribute.new(*attribute.split(":")) if attribute.include?(":")
    end
  end

So I have created in lib/generators/concerns a file called initializer.rb

module Initializer
  extend ActiveSupport::Concern

  # Initialize the generator accepting attributes as arguments  
  def initialize(*args, &block)
    super
    @attributes = []
    model_attributes.each do |attribute|
      @attributes << Rails::Generators::GeneratedAttribute.new(*attribute.split(":")) if attribute.include?(":")
    end
  end
end

And I include it this way in my generators:

class MyViewsGenerator < Rails::Generators::NamedBase
  include Initializer
  initialize()

But when I call a generation, it fails with this error :

Error: uninitialized constant MyViewsGenerator::Initializer.


Solution

  • To be able to use the methods from concern module as an instance methods in other classes, it should go into the included block.

    To make methods from concern class methods, you would put them into ClassMethods module.

    Since you call initialize() as a class method, you should actually put in inside ClassMethods module:

    module Initializer
      extend ActiveSupport::Concern
    
       included do # instance methods goes here
        end
    
        module ClassMethods # class methods goes here
          # Initialize the generator accepting attributes as arguments
          def initialize(*args, &block)
           # ...
          end
        end
    
     end
    

    By convention concerns modules are put into models/concerns/ folder.