Skip to content

Commit 5797c73

Browse files
authored
Merge pull request #1166 from kloeckner-i/feature/support_primary_keys_in_relationships
Added support for :primary_key in sorting on relationships
2 parents 7136bdd + 6946014 commit 5797c73

4 files changed

Lines changed: 57 additions & 8 deletions

File tree

lib/jsonapi/active_relation_resource_finder.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,10 +435,11 @@ def _build_joins(associations)
435435
associations.inject do |prev, current|
436436
prev_table_name = _join_table_name(prev)
437437
curr_table_name = _join_table_name(current)
438+
relationship_primary_key = current.options.fetch(:primary_key, "id")
438439
if current.belongs_to?
439-
joins << "LEFT JOIN #{current.table_name} AS #{curr_table_name} ON #{curr_table_name}.id = #{prev_table_name}.#{current.foreign_key}"
440+
joins << "LEFT JOIN #{current.table_name} AS #{curr_table_name} ON #{curr_table_name}.#{relationship_primary_key} = #{prev_table_name}.#{current.foreign_key}"
440441
else
441-
joins << "LEFT JOIN #{current.table_name} AS #{curr_table_name} ON #{curr_table_name}.#{current.foreign_key} = #{prev_table_name}.id"
442+
joins << "LEFT JOIN #{current.table_name} AS #{curr_table_name} ON #{curr_table_name}.#{current.foreign_key} = #{prev_table_name}.#{relationship_primary_key}"
442443
end
443444

444445
current
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
require File.expand_path('../../test_helper', __FILE__)
2+
3+
def set_content_type_header!
4+
@request.headers['Content-Type'] = JSONAPI::MEDIA_TYPE
5+
end
6+
7+
class WidgetsControllerTest < ActionController::TestCase
8+
def teardown
9+
Widget.delete_all
10+
Indicator.delete_all
11+
Agency.delete_all
12+
end
13+
14+
def test_fetch_widgets_sort_by_agency_name
15+
agency_1 = Agency.create! name: 'beta'
16+
agency_2 = Agency.create! name: 'alpha'
17+
indicator_1 = Indicator.create! import_id: 'foobar', name: 'bar', agency: agency_1
18+
indicator_2 = Indicator.create! import_id: 'foobar2', name: 'foo', agency: agency_2
19+
Widget.create! name: 'bar', indicator: indicator_1
20+
widget = Widget.create! name: 'foo', indicator: indicator_2
21+
assert_cacheable_get :index, params: {sort: 'indicator.agency.name'}
22+
assert_response :success
23+
assert_equal widget.id.to_s, json_response['data'].first['id']
24+
end
25+
end
26+
27+
class IndicatorsControllerTest < ActionController::TestCase
28+
def teardown
29+
Widget.delete_all
30+
Indicator.delete_all
31+
Agency.delete_all
32+
end
33+
34+
def test_fetch_indicators_sort_by_widgets_name
35+
agency = Agency.create! name: 'test'
36+
indicator_1 = Indicator.create! import_id: 'bar', name: 'bar', agency: agency
37+
indicator_2 = Indicator.create! import_id: 'foo', name: 'foo', agency: agency
38+
Widget.create! name: 'omega', indicator: indicator_1
39+
Widget.create! name: 'beta', indicator: indicator_1
40+
Widget.create! name: 'alpha', indicator: indicator_2
41+
Widget.create! name: 'zeta', indicator: indicator_2
42+
assert_cacheable_get :index, params: {sort: 'widgets.name'}
43+
assert_response :success
44+
assert_equal indicator_2.id.to_s, json_response['data'].first['id']
45+
assert_equal 2, json_response['data'].size
46+
end
47+
end

test/fixtures/active_record.rb

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -341,13 +341,14 @@
341341

342342
create_table :indicators, force: true do |t|
343343
t.string :name
344+
t.string :import_id
344345
t.integer :agency_id, null: false
345346
t.timestamps null: false
346347
end
347348

348349
create_table :widgets, force: true do |t|
349350
t.string :name
350-
t.integer :indicator_id, null: false
351+
t.string :indicator_import_id, null: false
351352
t.timestamps null: false
352353
end
353354

@@ -724,11 +725,11 @@ class Agency < ActiveRecord::Base
724725

725726
class Indicator < ActiveRecord::Base
726727
belongs_to :agency
727-
has_many :widgets
728+
has_many :widgets, primary_key: :import_id, foreign_key: :indicator_import_id
728729
end
729730

730731
class Widget < ActiveRecord::Base
731-
belongs_to :indicator
732+
belongs_to :indicator, primary_key: :import_id, foreign_key: :indicator_import_id
732733
end
733734

734735
class Robot < ActiveRecord::Base
@@ -2046,7 +2047,7 @@ class AgencyResource < JSONAPI::Resource
20462047
class IndicatorResource < JSONAPI::Resource
20472048
attributes :name
20482049
has_one :agency
2049-
has_many :widgets
2050+
has_many :widgets, foreign_key: :indicator_import_id, primary_key: :import_id
20502051

20512052
def self.sortable_fields(_context = nil)
20522053
super + [:'widgets.name']
@@ -2055,7 +2056,7 @@ def self.sortable_fields(_context = nil)
20552056

20562057
class WidgetResource < JSONAPI::Resource
20572058
attributes :name
2058-
has_one :indicator
2059+
has_one :indicator, foreign_key: :indicator_import_id, primary_key: :import_id
20592060

20602061
def self.sortable_fields(_context = nil)
20612062
super + [:'indicator.agency.name']

test/unit/resource/active_relation_resource_finder_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class ARPostResource < JSONAPI::Resource
44
model_name 'Post'
55
attribute :headline, delegate: :title
66
has_one :author
7-
has_many :tags
7+
has_many :tags, primary_key: :tags_import_id
88
end
99

1010
class ActiveRelationResourceFinderTest < ActiveSupport::TestCase

0 commit comments

Comments
 (0)