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?
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?
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
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?.
[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
.