Skip to content

Commit 8b971a8

Browse files
authored
Support the use of primary keys other than "id" in ActiveRecord. (#237)
Previously the diffing code made an assumption that "id" would always be the primary field. This is not always the case, and the use of `read_attribute(:id)` is deprecated in rails/rails@39997a0. This changes adds support for use of custom primary key fields, and updates the Person test model to use the "person_id" primary key. Note that this will almost certainly still run into issues if the model uses the newly introduced composite primary key type, so this would require additional changes outside the scope of this fix.
1 parent caa72ab commit 8b971a8

File tree

7 files changed

+39
-18
lines changed

7 files changed

+39
-18
lines changed

lib/super_diff/active_record/inspection_tree_builders/active_record_model.rb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ def self.applies_to?(value)
66
value.is_a?(::ActiveRecord::Base)
77
end
88

9+
def id
10+
object.class.primary_key
11+
end
12+
913
def call
1014
Core::InspectionTree.new do |t1|
1115
t1.as_lines_when_rendering_to_lines(
@@ -21,13 +25,17 @@ def call
2125

2226
t1.nested do |t2|
2327
t2.insert_separated_list(
24-
["id"] + (object.attributes.keys.sort - ["id"])
28+
[id] + (object.attributes.keys.sort - [id])
2529
) do |t3, name|
2630
t3.as_prefix_when_rendering_to_lines do |t4|
2731
t4.add_text "#{name}: "
2832
end
2933

30-
t3.add_inspection_of object.read_attribute(name)
34+
if name == id
35+
t3.add_inspection_of object.id
36+
else
37+
t3.add_inspection_of object.read_attribute(name)
38+
end
3139
end
3240
end
3341

lib/super_diff/active_record/monkey_patches.rb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
class ActiveRecord::Base
33
# TODO: Remove this monkey patch if possible
44
def attributes_for_super_diff
5-
(attributes.keys.sort - ["id"]).reduce({ id: id }) do |hash, key|
6-
hash.merge(key.to_sym => attributes[key])
7-
end
5+
id_attr = self.class.primary_key
6+
7+
(attributes.keys.sort - [id_attr]).reduce(
8+
{ id_attr.to_sym => id }
9+
) { |hash, key| hash.merge(key.to_sym => attributes[key]) }
810
end
911
end
1012
# rubocop:enable Style/BracesAroundHashParameters, Style/ClassAndModuleChildren

lib/super_diff/active_record/operation_tree_builders/active_record_model.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@ def self.applies_to?(expected, actual)
99

1010
protected
1111

12+
def id
13+
expected.class.primary_key
14+
end
15+
1216
def attribute_names
13-
["id"] + (expected.attributes.keys.sort - ["id"])
17+
[id] + (expected.attributes.keys.sort - [id])
1418
end
1519
end
1620
end

spec/support/integration/matchers/produce_output_when_run_matcher.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def initialize(expected_output)
1212
end
1313

1414
def removing_object_ids
15-
first_replacing(/#<([\w:]+):0x[a-f0-9]+/, '#<\1')
15+
first_replacing(/#<([\w_:]+):0x[a-f0-9]+/, '#<\1')
1616
self
1717
end
1818

spec/support/models/active_record/person.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module Test
33
module Models
44
module ActiveRecord
55
class Person < ::ActiveRecord::Base
6+
self.primary_key = "person_id"
67
end
78
end
89
end
@@ -13,7 +14,13 @@ class Person < ::ActiveRecord::Base
1314
config.before do
1415
ActiveRecord::Base
1516
.connection
16-
.create_table(:people, force: true) do |t|
17+
.create_table(
18+
:people,
19+
id: false,
20+
primary_key: "person_id",
21+
force: true
22+
) do |t|
23+
t.primary_key :person_id, null: false
1724
t.string :name, null: false
1825
t.integer :age, null: false
1926
end

spec/support/shared_examples/active_record.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
proc do
8787
line do
8888
plain "Expected "
89-
actual %|#<SuperDiff::Test::Models::ActiveRecord::Person id: nil, age: 31, name: "Elliot">|
89+
actual %|#<SuperDiff::Test::Models::ActiveRecord::Person person_id: nil, age: 31, name: "Elliot">|
9090
end
9191

9292
line do
@@ -244,7 +244,7 @@
244244
proc do
245245
line do
246246
plain "Expected "
247-
actual %|{ name: "Marty McFly", shipping_address: #<SuperDiff::Test::Models::ActiveRecord::Person id: nil, age: 31, name: "Elliot"> }|
247+
actual %|{ name: "Marty McFly", shipping_address: #<SuperDiff::Test::Models::ActiveRecord::Person person_id: nil, age: 31, name: "Elliot"> }|
248248
end
249249

250250
line do
@@ -265,7 +265,7 @@
265265
expected_line %|- zip: "90382"|
266266
expected_line "- }>"
267267
actual_line "+ shipping_address: #<SuperDiff::Test::Models::ActiveRecord::Person {"
268-
actual_line "+ id: nil,"
268+
actual_line "+ person_id: nil,"
269269
actual_line "+ age: 31,"
270270
actual_line %|+ name: "Elliot"|
271271
actual_line "+ }>"
@@ -390,7 +390,7 @@
390390
proc do
391391
line do
392392
plain "Expected "
393-
actual %|[#<SuperDiff::Test::Models::ActiveRecord::Query @results=#<ActiveRecord::Relation [#<SuperDiff::Test::Models::ActiveRecord::Person id: 1, age: 20, name: "Murphy">]>>]|
393+
actual %|[#<SuperDiff::Test::Models::ActiveRecord::Query @results=#<ActiveRecord::Relation [#<SuperDiff::Test::Models::ActiveRecord::Person person_id: 1, age: 20, name: "Murphy">]>>]|
394394
end
395395

396396
line do
@@ -404,7 +404,7 @@
404404
plain_line " #<SuperDiff::Test::Models::ActiveRecord::Query {"
405405
plain_line " @results=#<ActiveRecord::Relation ["
406406
plain_line " #<SuperDiff::Test::Models::ActiveRecord::Person {"
407-
plain_line " id: 1,"
407+
plain_line " person_id: 1,"
408408
# expected_line %|- age: 19,| # TODO
409409
expected_line "- age: 19"
410410
actual_line "+ age: 20,"

spec/unit/active_record/object_inspection_spec.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
as_lines: false
1515
)
1616
expect(string).to eq(
17-
%(#<SuperDiff::Test::Models::ActiveRecord::Person id: nil, age: 31, name: "Elliot">)
17+
%(#<SuperDiff::Test::Models::ActiveRecord::Person person_id: nil, age: 31, name: "Elliot">)
1818
)
1919
end
2020
end
@@ -42,7 +42,7 @@
4242
an_object_having_attributes(
4343
type: :delete,
4444
indentation_level: 2,
45-
prefix: "id: ",
45+
prefix: "person_id: ",
4646
value: "nil",
4747
add_comma: true
4848
),
@@ -91,7 +91,7 @@
9191
)
9292

9393
expect(string).to eq(
94-
%(#<ActiveRecord::Relation [#<SuperDiff::Test::Models::ActiveRecord::Person id: 1, age: 19, name: "Marty">, #<SuperDiff::Test::Models::ActiveRecord::Person id: 2, age: 17, name: "Jennifer">]>)
94+
%(#<ActiveRecord::Relation [#<SuperDiff::Test::Models::ActiveRecord::Person person_id: 1, age: 19, name: "Marty">, #<SuperDiff::Test::Models::ActiveRecord::Person person_id: 2, age: 17, name: "Jennifer">]>)
9595
)
9696
end
9797
end
@@ -132,7 +132,7 @@
132132
an_object_having_attributes(
133133
type: :delete,
134134
indentation_level: 3,
135-
prefix: "id: ",
135+
prefix: "person_id: ",
136136
value: "1",
137137
add_comma: true
138138
),
@@ -165,7 +165,7 @@
165165
an_object_having_attributes(
166166
type: :delete,
167167
indentation_level: 3,
168-
prefix: "id: ",
168+
prefix: "person_id: ",
169169
value: "2",
170170
add_comma: true
171171
),

0 commit comments

Comments
 (0)