2

How can I obtain model file path in rails? I want something like that:

MyModel.file_path

expected result: "/app/models/my_model.rb

It's possible to do in rails or I need to create file name from models name and find it in models directory?

maki
  • 525
  • 1
  • 7
  • 27

3 Answers3

3

I think you have to build it, but is fairly simple.

Here it goes:

def model_path
  model_file = self.class.name.split("::").map {|c| c.downcase }.join('/') + '.rb'
  path = Rails.root.join('app/models/').join(model_file)
end
Rafael Oliveira
  • 2,823
  • 4
  • 33
  • 50
2

You can use __FILE__ to refer to the current file path:

def self.file_path
  File.expand_path(__FILE__)
end

or

def self.file_path
  __FILE__
end

Note that the Ruby version matters for what __FILE__ returns. See What does __FILE__ mean in Ruby?.

Community
  • 1
  • 1
0

[Adapted from part of this answer to a more general question]

In a simple Rails application, the application's model classes are defined within its app/models directory, with a file path that can be derived deterministically from the class name. A method to retrieve this path can be defined in a specific model class MyModel like so:

class MyModel
  def self.file_path
    Rails.root.join('app', 'models', "#{klass.name.underscore}.rb").to_s
  end
end

For example, this particular model class MyModel would be defined in APP_ROOT/app/models/my_model.rb, where APP_ROOT is the application's root directory path.

To generalize this, one can define such a method in all model classes and consider extensions of the simple Rails path configuration. In a Rails application that defines custom paths for model definitions, one must consider all of them. Also, since an arbitrary model class may be defined in any Rails engine loaded by the application, one must also look in all loaded engines, taking into account their custom paths. The following code combines these considerations.

module ActiveRecord
  class Base
    def self.file_path
      candidates = Rails.application.config.paths['app/models'].map do |model_root|
        Rails.root.join(model_root, "#{name.underscore}.rb").to_s
      end
      candidates += Rails::Engine::Railties.engines.flat_map do |engine|
        engine.paths['app/models'].map do |model_root|
          engine.root.join(model_root, "#{name.underscore}.rb").to_s
        end
      end
      candidates.find { |path| File.exist?(path) }
    end
  end
end

To make Rails apply this monkey patch, require it in config/initializers/active_record.rb.

nisavid
  • 163
  • 1
  • 7