Coder Social home page Coder Social logo

Comments (4)

guigs avatar guigs commented on June 9, 2024 2

Here's a monkey patch we are using that find classes based on zeitwerk loader.
Our use case is for loading classes within namespaces. I'm not sure if it works with collapsed dirs, but maybe you can modify it to work.

Put in an initializer:

# frozen_string_literal: true

if Rails.env.development?
  require 'annotate'

  module AnnotateModelsWithZeitwerk
    def get_model_class(file)
      loader = Rails.autoloaders.main
      root_dirs = loader.dirs(namespaces: true) # or `root_dirs = loader.root_dirs` with zeitwerk < 2.6.1
      expanded_file = File.expand_path(file)
      root_dir, namespace = root_dirs.find do |dir, _|
        expanded_file.start_with?(dir)
      end
      _, filepath_relative_to_root_dir = expanded_file.split(root_dir)
      filepath_relative_to_root_dir = filepath_relative_to_root_dir[1..].sub(/\.rb$/, '')
      camelize = loader.inflector.camelize(filepath_relative_to_root_dir, nil)
      namespace.const_get(camelize)
    end
  end

  module AnnotateModels
    class << self
      prepend AnnotateModelsWithZeitwerk
    end
  end
end

from annotate_models.

ilvez avatar ilvez commented on June 9, 2024 1

I found that fork of this gem has solved those issues: https://github.com/drwl/annotaterb

I understand fork was done since this gem is unmaintained quite a long time now (2 years without release): https://www.reddit.com/r/rails/comments/13keyfm/i_spent_the_past_3_months_working_on_a_fork_of/

Nearly drop in replacement, but configuration file needs to be created instead of configuring in rake task.

from annotate_models.

joshuaclayton avatar joshuaclayton commented on June 9, 2024

I also ran into this issue earlier and had to adjust the example above slightly.

We're using collapsed directories as such:

# within config/application.rb
Rails.autoloaders.main.collapse("#{Rails.root}/app/domains/domain_name/models")
Rails.autoloaders.main.collapse("#{Rails.root}/app/domains/domain_name/controllers")
Rails.autoloaders.main.collapse("#{Rails.root}/app/domains/domain_name/lib")

Based on this, I adjusted the sample above to address const loading issues:

module AnnotateModelsWithZeitwerk
  def get_model_class(file)
    loader = Rails.autoloaders.main
    root_dirs = loader.dirs(namespaces: true) # or `root_dirs = loader.root_dirs` with zeitwerk < 2.6.1
    expanded_file = File.expand_path(file)
    root_dir, namespace = root_dirs.find do |dir, _|
      expanded_file.start_with?(dir)
    end
    _, filepath_relative_to_root_dir = expanded_file.split(root_dir)

    filepath_relative_to_root_dir = filepath_relative_to_root_dir[1..].sub(/\.rb$/, "")

    # changed

    # once we have the filepath_relative_to_root_dir, we need to see if it
    # falls within one of our Zeitwerk "collapsed" paths.
    if loader.collapse.any? { |path| path.include?(root_dir) && file.include?(path.split(root_dir)[1]) }
      # if the file is within a collapsed path, we then need to, for each
      # collapsed path, remove the root dir
      collapsed = loader.collapse.map { |path| path.split(root_dir)[1].sub(/^\//, "") }.to_set

      collapsed.each do |collapse|
        # next, we split the collapsed directory, e.g. `domain_name/models`, by
        # slash, and discard the domain_name
        _, *collapsed_namespace = collapse.split("/")

        # if there are any collapsed namespaces, e.g. `models`, we then remove
        # that from `filepath_relative_to_root_dir`.
        #
        # This would result in:
        #
        # previous filepath_relative_to_root_dir: domain_name/models/model_name
        # new filepath_relative_to_root_dir: domain_name/model_name
        if collapsed_namespace.any?
          filepath_relative_to_root_dir.sub!("/#{collapsed_namespace.last}", "")
        end
      end
    end

    # end changed

    camelize = loader.inflector.camelize(filepath_relative_to_root_dir, nil)
    namespace.const_get(camelize)
  end
end

from annotate_models.

drwl avatar drwl commented on June 9, 2024

@joshuaclayton @bazay, I took a stab at adding zeitwerk support in my fork, if you want to know more: drwl/annotaterb#82

from annotate_models.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.