11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
# File 'lib/rails-mcp-server/tools/analyze_models.rb', line 11
def call(model_name: nil)
unless current_project
message = "No active project. Please switch to a project first."
log(:warn, message)
return message
end
if model_name
log(:info, "Getting info for specific model: #{model_name}")
model_file = File.join(active_project_path, "app", "models", "#{underscore(model_name)}.rb")
unless File.exist?(model_file)
log(:warn, "Model file not found: #{model_name}")
message = "Model '#{model_name}' not found."
log(:warn, message)
return message
end
log(:debug, "Reading model file: #{model_file}")
model_content = File.read(model_file)
log(:debug, "Executing Rails runner to get schema information")
schema_info = execute_rails_command(
active_project_path,
"runner \"puts #{model_name}.column_names\""
)
associations = []
if model_content.include?("has_many")
has_many = model_content.scan(/has_many\s+:(\w+)/).flatten
associations << "Has many: #{has_many.join(", ")}" unless has_many.empty?
end
if model_content.include?("belongs_to")
belongs_to = model_content.scan(/belongs_to\s+:(\w+)/).flatten
associations << "Belongs to: #{belongs_to.join(", ")}" unless belongs_to.empty?
end
if model_content.include?("has_one")
has_one = model_content.scan(/has_one\s+:(\w+)/).flatten
associations << "Has one: #{has_one.join(", ")}" unless has_one.empty?
end
log(:debug, "Found #{associations.size} associations for model: #{model_name}")
<<~INFO
Model: #{model_name}
Schema:
#{schema_info}
Associations:
#{associations.empty? ? "None found" : associations.join("\n")}
Model Definition:
```ruby
#{model_content}
```
INFO
else
log(:info, "Listing all models")
models_dir = File.join(active_project_path, "app", "models")
unless File.directory?(models_dir)
message = "Models directory not found."
log(:warn, message)
return message
end
model_files = Dir.glob(File.join(models_dir, "**", "*.rb"))
.map { |f| f.sub("#{models_dir}/", "").sub(/\.rb$/, "") }
.sort
log(:debug, "Found #{model_files.size} model files")
"Models in the project:\n\n#{model_files.join("\n")}"
end
end
|