class Thecore::ThecorizeModelsGenerator

Public Instance Methods

add_has_many() click to toggle source
# File lib/generators/thecore/thecorize_models/thecorize_models_generator.rb, line 83
    def add_has_many
      say "Add Has Many Associations", :green
      # For each model in this gem
      @model_files.each do |entry|
        file = File.join(@plugin_models_dir,entry)
        # It must be an activerecord model class
        if is_applicationrecord?(file)
          # say "Looking for belongs_to in #{entry} and adding the relevant has_manies", :green

          # Polymorphic must be managed manually
          File.readlines(file).grep(/^(?!.*polymorphic.*)^[ \t]*belongs_to :(.*),.+/).each do |a|
            target_association = a[/:(.*?),/,1]
            # look if the file identified by association .rb exists
            associated_file = File.join(@plugin_models_dir,"#{target_association}.rb")
            starting_model = entry.split(".").first.pluralize
            # say "Found belongs_to association: #{target_association} for the model: #{starting_model}", :green
            # say "- Looking for model file: #{associated_file}", :green
            if File.exists?(associated_file)
              # say "The file in which to add has_many, exists and the has_many does not! #{associated_file}", :green
              # if true, check that the association is non existent and add the association to that file
              inject_into_file associated_file, after: " < ApplicationRecord\n" do
                "\n\t\thas_many :#{starting_model}, inverse_of: :#{target_association}, dependent: :destroy\n"
              end unless has_has_many_association?(associated_file, starting_model)
            else
              # otherwise (the file does not exist) check if the initializer for concerns exists,
              # For each model in this gem
              initializer_name = "associations_#{target_association}_concern.rb"
              initializer initializer_name do
"require 'active_support/concern'

module #{target_association.classify}AssociationsConcern
  extend ActiveSupport::Concern
  included do
  end
end

# include the extension
# #{target_association.classify}.send(:include, #{target_association.classify}AssociationsConcern)
"
              end unless File.exists?(File.join(@plugin_initializers_dir, initializer_name))

              # AGGIUNGO L'INCLUDE
              say "Adding after_initialize file", :green
              after_initialize_file_name = "#{@name}_after_initialize.rb"
              after_initialize_file_fullpath = File.join(@plugin_initializers_dir, after_initialize_file_name)
              initializer after_initialize_file_name do
                "Rails.application.configure do\n\tconfig.after_initialize do\n\tend\nend"
              end unless File.exists?(after_initialize_file_fullpath)
              inject_into_file after_initialize_file_fullpath, after: "config.after_initialize do\n" do
                "\n\t\t#{target_association.classify}.send(:include, #{target_association.classify}AssociationsConcern)\n"
              end

              # then add to it the has_many declaration
              # TODO: only if it doesn't already exists
              inject_into_file File.join(@plugin_initializers_dir, initializer_name), after: "included do\n" do
                "\n\t\thas_many :#{starting_model}, inverse_of: :#{target_association}, dependent: :destroy\n"
              end
            end
          end
        end
      end
    end
add_has_many_through() click to toggle source
# File lib/generators/thecore/thecorize_models/thecorize_models_generator.rb, line 147
    def add_has_many_through
      say "Add Has Many Through Associations", :green
      # I'ts just an approximation, but for now it could work
      @model_files.each do |model|
        association_model = model.split(".").first
        file = File.join(@plugin_models_dir,model)
        # It must be an activerecord model class
        model_with_belongs_to = File.readlines(file).grep(/^[ \t]*belongs_to :.*$/)
        if model_with_belongs_to.size == 2
          if yes?("Is #{model} an association model for a has_many through relation?", :red)
            # getting both the belongs_to models, find their model files, and add the through to each other
            left_side = model_with_belongs_to.first[/:(.*?),/,1]
            right_side = model_with_belongs_to.last[/:(.*?),/,1]
            # This side of the through
            inject_into_file File.join(@plugin_models_dir, "#{left_side}.rb"), after: " < ApplicationRecord\n" do
              #has_many :rooms, through: :chosen_rooms, inverse_of: :chosen_decks
"
  has_many :#{right_side.pluralize}, through: :#{association_model.pluralize}, inverse_of: :#{left_side.pluralize}
"
            end unless is_has_many_through? file, right_side.pluralize, association_model.pluralize
            # Other side of the through
            inject_into_file File.join(@plugin_models_dir, "#{right_side}.rb"), after: " < ApplicationRecord\n" do
              #has_many :rooms, through: :chosen_rooms, inverse_of: :chosen_decks
"
  has_many :#{left_side.pluralize}, through: :#{association_model.pluralize}, inverse_of: :#{right_side.pluralize}
"
            end unless is_has_many_through? file, left_side.pluralize, association_model.pluralize
          end
        end
      end
    end
add_rails_admin_reference() click to toggle source
# File lib/generators/thecore/thecorize_models/thecorize_models_generator.rb, line 40
    def add_rails_admin_reference
      say "Add rails_admin declaration only in files which are ActiveRecords and don't already have that declaration", :green
      # For each model in this gem
      @model_files.each do |entry|
        # It must be a class and don't have rails_admin declaration
        file = File.join(@plugin_models_dir,entry)
        # say "Checking file #{file}", :red
        if is_applicationrecord?(file) && !has_rails_admin_declaration?(file)
          # say "Adding rails_admin to #{entry}", :green
          # Add rails admin declaration
          inject_into_file file, before: /^end/ do
"
  RailsAdmin.config do |config|
    config.model self.name.underscore.capitalize.classify do
      navigation_label I18n.t('admin.settings.label')
      navigation_icon 'fa fa-file'
    end
  end
"
          end
        end
      end
    end
complete_belongs_to() click to toggle source
# File lib/generators/thecore/thecorize_models/thecorize_models_generator.rb, line 65
def complete_belongs_to
  say "Completes Belongs To Associations", :green
  # For each model in this gem
  @model_files.each do |entry|
    # It must be a class and don't have rails_admin declaration
    file = File.join(@plugin_models_dir,entry)
    # say "Checking file #{file}", :red
    if is_applicationrecord?(file)
      # say "Adding inverse_of to all belongs_to in #{entry}", :green
      # belongs_to that don't have inverse_of
      gsub_file file, /^(?!.*inverse_of.*)^[ \t]*belongs_to.*$/ do |match|
        match << ", inverse_of: :#{entry.split(".").first.pluralize}"
      end
    end
  end
end
detect_polymorphic_associations() click to toggle source
# File lib/generators/thecore/thecorize_models/thecorize_models_generator.rb, line 180
    def detect_polymorphic_associations
      say "Detect polymorphic Associations", :green
      # For each model in this gem
      # say "MODEL FILES: #{@model_files.inspect} "
      @model_files.each do |model|
        file = File.join(@plugin_models_dir,model)
        # It must be an activerecord model class
        # belongs_to :rowable, polymorphic: true, inverse_of: :rows
        polymorphics = File.readlines(file).grep(/^[ \t]*belongs_to :.*polymorphic.*/)
        polymorphics.each do |polymorphic_belongs_to|
          polymorphic_target_association = polymorphic_belongs_to[/:(.*?),/,1]
          # Just keeping the models that are not this model, and
          answers = ask_question_multiple_choice @model_files.reject {|m| m == model || has_polymorphic_has_many?(File.join(@plugin_models_dir,m), polymorphic_target_association)}, "Where do you want to add the polymorphic has_many called #{polymorphic_target_association} found in #{model}?"
          answers.each do |answer|
            # Add the polymorphic has_name declaration
            inject_into_file File.join(@plugin_models_dir, answer), after: " < ApplicationRecord\n" do
"
  has_many :#{model.split(".").first.pluralize}, as: :#{polymorphic_target_association}, inverse_of: :#{answer.split(".").first.singularize}, dependent: :destroy
"
            end
          end
        end
      end
    end
init_constants() click to toggle source
# File lib/generators/thecore/thecorize_models/thecorize_models_generator.rb, line 6
def init_constants
  say "Setting the variables", :green
  @plugin_path = @destination_stack.first.match(Regexp.new("^.*#{@name}"))[0]
  @parent_path = File.expand_path("..", @plugin_path)
  @plugin_parent_name = @parent_path.split(File::SEPARATOR).last
  @plugin_initializers_dir = File.join(@plugin_path, "config", "initializers")
  @plugin_models_dir = File.join(@plugin_path, "app", "models")
  @plugin_lib_file = File.join(@plugin_path, "lib", @name, "engine.rb")
  Dir.chdir @plugin_models_dir do
    # Getting all the models that are activerecords:
    @model_files = Dir.glob("*.rb").map do |model|
      file = File.join(@plugin_models_dir,model)
      model if is_applicationrecord?(file)
    end.compact
  end
end
replace_active_record() click to toggle source
# File lib/generators/thecore/thecorize_models/thecorize_models_generator.rb, line 24
def replace_active_record
  say "Replace ActiveRecord::Base with ApplicationRecord", :green
  # For each model in this gem
  @model_files.each do |entry|
    # It must be a class and don't have rails_admin declaration
    file = File.join(@plugin_models_dir, entry)
    # say "Checking file #{file}", :red
    if is_activerecord?(file) && !has_rails_admin_declaration?(file)
      # say "Replacing ActiveRecord::Base into #{entry}", :green
      # Add rails admin declaration
      gsub_file file, "ActiveRecord::Base", "ApplicationRecord"
    end
  end
end

Private Instance Methods

ask_question_multiple_choice(models, question = "Choose among one of these, please.") click to toggle source
# File lib/generators/thecore/thecorize_models/thecorize_models_generator.rb, line 207
def ask_question_multiple_choice models, question = "Choose among one of these, please."
  return [] if models.empty?
  # raccolgo tutte le risposte che non siano cancel
  # e ritorno l'array
  return_array = []
  while (answer ||= "") != "cancel"
    remaining_models = (models-return_array)
    break if remaining_models.empty?
    answer = ask question, :red, limited_to: remaining_models.push("cancel").uniq
    break if answer == "cancel"
    return_array.push answer
  end
  return return_array
end
has_add_to_migrations_declaration?(file) click to toggle source
# File lib/generators/thecore/thecorize_models/thecorize_models_generator.rb, line 246
def has_add_to_migrations_declaration? file
  (File.readlines(file).grep(/^[ \t]*initializer '[a-zA-Z0-9]+\.add_to_migrations' do \|app\|/).size > 0) rescue false
end
has_has_many_association?(file, assoc) click to toggle source
# File lib/generators/thecore/thecorize_models/thecorize_models_generator.rb, line 250
def has_has_many_association? file, assoc
  reg_def = "^[ \\t]+has_many[ \\t]+:#{assoc}"
  (File.readlines(file).grep(Regexp.new(reg_def)).size > 0) rescue false
end
has_polymorphic_has_many?(file, polymorphic_name) click to toggle source
# File lib/generators/thecore/thecorize_models/thecorize_models_generator.rb, line 226
def has_polymorphic_has_many? file, polymorphic_name
  (File.readlines(file).grep(/^[ \t]*has_many.+as: :#{polymorphic_name}.*/).size > 0) rescue false
end
has_rails_admin_declaration?(file) click to toggle source
# File lib/generators/thecore/thecorize_models/thecorize_models_generator.rb, line 238
def has_rails_admin_declaration? file
  (File.readlines(file).grep(/^[ \t]*RailsAdmin.config do/).size > 0) rescue false
end
is_activerecord?(file) click to toggle source
# File lib/generators/thecore/thecorize_models/thecorize_models_generator.rb, line 230
def is_activerecord? file
  (File.readlines(file).grep(/^class [A-Za-z0-9]+ < ActiveRecord::Base/).size > 0) rescue false
end
is_applicationrecord?(file) click to toggle source
# File lib/generators/thecore/thecorize_models/thecorize_models_generator.rb, line 234
def is_applicationrecord? file
  (File.readlines(file).grep(/^class [A-Za-z0-9]+ < ApplicationRecord/).size > 0) rescue false
end
is_engine?(file) click to toggle source
# File lib/generators/thecore/thecorize_models/thecorize_models_generator.rb, line 242
def is_engine? file
  (File.readlines(file).grep(/^[ \t]*class Engine < ::Rails::Engine/).size > 0) rescue false
end
is_has_many_through?(file, assoc, through) click to toggle source
# File lib/generators/thecore/thecorize_models/thecorize_models_generator.rb, line 222
def is_has_many_through? file, assoc, through
  (File.readlines(file).grep(/^[ \t]*has_many[ \t]+:#{assoc},[ \t]+through:[ \t]+:#{through}.*/).size > 0) rescue false
end