Skip to content

Commit 8c0e73a

Browse files
authored
Add primary key indicator to model hover response (#316)
Closes #313
1 parent 138fc45 commit 8c0e73a

File tree

6 files changed

+77
-4
lines changed

6 files changed

+77
-4
lines changed

lib/ruby_lsp/ruby_lsp_rails/hover.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ def generate_column_content(name)
8383

8484
@response_builder.push(
8585
model[:columns].map do |name, type|
86-
"**#{name}**: #{type}\n"
86+
primary_key_suffix = " (PK)" if model[:primary_keys].include?(name)
87+
"**#{name}**: #{type}#{primary_key_suffix}\n"
8788
end.join("\n"),
8889
category: :documentation,
8990
)

lib/ruby_lsp/ruby_lsp_rails/server.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ def resolve_database_info_from_model(model_name)
9191
info = {
9292
result: {
9393
columns: const.columns.map { |column| [column.name, column.type] },
94+
primary_keys: Array(const.primary_key),
9495
},
9596
}
9697

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# typed: true
2+
# frozen_string_literal: true
3+
4+
class CompositePrimaryKey < ApplicationRecord
5+
end
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class CreateCompositePk < ActiveRecord::Migration[7.1]
2+
def change
3+
create_table :composite_primary_keys, primary_key: [:order_id, :product_id] do |t|
4+
t.integer :order_id
5+
t.integer :product_id
6+
t.text :note
7+
8+
t.timestamps
9+
end
10+
end
11+
end

test/dummy/db/schema.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,15 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema[7.1].define(version: 2023_10_19_180159) do
13+
ActiveRecord::Schema[7.1].define(version: 2024_04_03_145625) do
14+
create_table "composite_primary_keys", primary_key: ["order_id", "product_id"], force: :cascade do |t|
15+
t.integer "order_id"
16+
t.integer "product_id"
17+
t.text "note"
18+
t.datetime "created_at", null: false
19+
t.datetime "updated_at", null: false
20+
end
21+
1422
create_table "posts", force: :cascade do |t|
1523
t.string "title"
1624
t.text "body"

test/ruby_lsp_rails/hover_test.rb

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class HoverTest < ActiveSupport::TestCase
2424
["created_at", "datetime"],
2525
["updated_at", "datetime"],
2626
],
27+
primary_keys: ["id"],
2728
}
2829

2930
RunnerClient.any_instance.stubs(model: expected_response)
@@ -44,7 +45,7 @@ class User < ApplicationRecord
4445
[Schema](file://#{dummy_root}/db/schema.rb)
4546
4647
47-
**id**: integer
48+
**id**: integer (PK)
4849
4950
**first_name**: string
5051
@@ -69,6 +70,7 @@ class User < ApplicationRecord
6970
["created_at", "datetime"],
7071
["updated_at", "datetime"],
7172
],
73+
primary_keys: ["id"],
7274
}
7375

7476
RunnerClient.any_instance.stubs(model: expected_response)
@@ -85,7 +87,7 @@ class User < ApplicationRecord
8587
assert_equal(<<~CONTENT.chomp, response.contents.value)
8688
[Schema](file://#{dummy_root}/db/schema.rb)
8789
88-
**id**: integer
90+
**id**: integer (PK)
8991
9092
**first_name**: string
9193
@@ -99,10 +101,54 @@ class User < ApplicationRecord
99101
CONTENT
100102
end
101103

104+
test "returns column information for models with composite primary keys" do
105+
expected_response = {
106+
schema_file: "#{dummy_root}/db/schema.rb",
107+
columns: [
108+
["order_id", "integer"],
109+
["product_id", "integer"],
110+
["note", "string"],
111+
["created_at", "datetime"],
112+
["updated_at", "datetime"],
113+
],
114+
primary_keys: ["order_id", "product_id"],
115+
}
116+
117+
RunnerClient.any_instance.stubs(model: expected_response)
118+
119+
response = hover_on_source(<<~RUBY, { line: 3, character: 0 })
120+
class CompositePrimaryKey < ApplicationRecord
121+
end
122+
123+
CompositePrimaryKey
124+
RUBY
125+
126+
assert_equal(<<~CONTENT.chomp, response.contents.value)
127+
```ruby
128+
CompositePrimaryKey
129+
```
130+
131+
**Definitions**: [fake.rb](file:///fake.rb#L1,1-2,4)
132+
[Schema](file://#{dummy_root}/db/schema.rb)
133+
134+
135+
**order_id**: integer (PK)
136+
137+
**product_id**: integer (PK)
138+
139+
**note**: string
140+
141+
**created_at**: datetime
142+
143+
**updated_at**: datetime
144+
CONTENT
145+
end
146+
102147
test "handles `db/structure.sql` instead of `db/schema.rb`" do
103148
expected_response = {
104149
schema_file: "#{dummy_root}/db/structure.sql",
105150
columns: [],
151+
primary_keys: [],
106152
}
107153

108154
RunnerClient.any_instance.stubs(model: expected_response)
@@ -124,6 +170,7 @@ class User < ApplicationRecord
124170
expected_response = {
125171
schema_file: nil,
126172
columns: [],
173+
primary_keys: [],
127174
}
128175

129176
RunnerClient.any_instance.stubs(model: expected_response)

0 commit comments

Comments
 (0)