Skip to content

Commit 4b9eb4d

Browse files
committed
Handle custom view paths of controller subclasses
While here, we undo changes in code lens to handle custom view paths. If this approach is accepted, we can always update the code lens later.
1 parent 1dd9370 commit 4b9eb4d

File tree

3 files changed

+40
-18
lines changed

3 files changed

+40
-18
lines changed

lib/ruby_lsp/ruby_lsp_rails/code_lens.rb

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -194,14 +194,7 @@ def add_jump_to_view(node)
194194
action_name = node.name
195195
controller_name = underscore(class_name.delete_suffix("Controller"))
196196

197-
controller_info = @client.controller(class_name)
198-
return unless controller_info
199-
200-
view_paths = controller_info[:view_paths].select do |path|
201-
path.start_with?(@client.rails_root)
202-
end
203-
204-
view_uris = Dir.glob("{#{view_paths.join(",")}}/#{controller_name}/#{action_name}*").filter_map do |path|
197+
view_uris = Dir.glob("#{@client.rails_root}/app/views/#{controller_name}/#{action_name}*").filter_map do |path|
205198
# it's possible we could have a directory with the same name as the action, so we need to skip those
206199
next if File.directory?(path)
207200

lib/ruby_lsp/ruby_lsp_rails/definition.rb

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# typed: strict
22
# frozen_string_literal: true
33

4+
require "pathname"
5+
46
module RubyLsp
57
module Rails
68
# ![Definition demo](../../definition.gif)
@@ -280,20 +282,26 @@ def view_template_details(arguments)
280282
end
281283
end
282284

285+
# Determine controller name for given template path based on template
286+
# directory and view paths.
287+
#
283288
#: (String template_path) -> String?
284289
def controller_for_template(template_path)
285-
controller_info = @client.controller("ActionController::Base")
286-
return unless controller_info
287-
288-
view_paths = controller_info[:view_paths]
289-
template_directory = File.dirname(template_path)
290-
291-
view_path = view_paths.find { |path| template_directory.start_with?(path + "/") }
292-
return unless view_path
290+
template_directory = Pathname(template_path).dirname.relative_path_from(@client.rails_root)
291+
directory_segments = template_directory.each_filename.to_a
292+
possible_controller_paths = (1..directory_segments.count).map do |n|
293+
directory_segments.last(n).join("/")
294+
end
293295

294-
controller_path = template_directory.delete_prefix(view_path + "/")
296+
controller_path = possible_controller_paths.find do |controller_path|
297+
controller_name = camelize(controller_path) + "Controller"
298+
view_paths = @client.controller(controller_name)&.dig(:view_paths) || []
299+
view_paths.any? do |view_path|
300+
File.join(view_path, controller_path) == File.dirname(template_path)
301+
end
302+
end
295303

296-
camelize(controller_path) + "Controller"
304+
camelize(controller_path) + "Controller" if controller_path
297305
end
298306
end
299307
end

test/ruby_lsp_rails/definition_test.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,27 @@ def name; end
503503
FileUtils.rm("#{dummy_root}/app/views/users/_partial.html.erb")
504504
end
505505

506+
test "handles custom view paths" do
507+
FileUtils.mkdir_p("#{dummy_root}/app/custom/views/admin")
508+
FileUtils.touch("#{dummy_root}/app/custom/views/admin/_partial.html.erb")
509+
File.write("#{dummy_root}/app/controllers/admin_controller.rb", <<~RUBY)
510+
class AdminController < ApplicationController
511+
prepend_view_path "#{dummy_root}/app/custom/views"
512+
end
513+
RUBY
514+
515+
uri = Kernel.URI("file://#{dummy_root}/app/custom/views/admin/render.html.erb")
516+
source = <<~ERB
517+
<%= render "partial" %>
518+
ERB
519+
520+
response = generate_definitions_for_source(source, { line: 0, character: 12 }, uri)
521+
assert_equal("file://#{dummy_root}/app/custom/views/admin/_partial.html.erb", response.first.uri)
522+
ensure
523+
FileUtils.rm_r("#{dummy_root}/app/custom/views/admin")
524+
FileUtils.rm("#{dummy_root}/app/controllers/admin_controller.rb")
525+
end
526+
506527
test "handles template formats, variants and handlers" do
507528
FileUtils.touch("#{dummy_root}/app/views/users/_partial.html.erb")
508529
FileUtils.touch("#{dummy_root}/app/views/users/_partial.text.erb")

0 commit comments

Comments
 (0)