diff --git a/lib/jsonapi/active_relation_resource_finder.rb b/lib/jsonapi/active_relation_resource_finder.rb index af6595a01..dab43eddc 100644 --- a/lib/jsonapi/active_relation_resource_finder.rb +++ b/lib/jsonapi/active_relation_resource_finder.rb @@ -434,10 +434,11 @@ def _build_joins(associations) associations.inject do |prev, current| prev_table_name = _join_table_name(prev) curr_table_name = _join_table_name(current) + relationship_primary_key = current.options.fetch(:primary_key, "id") if current.belongs_to? - joins << "LEFT JOIN #{current.table_name} AS #{curr_table_name} ON #{curr_table_name}.id = #{prev_table_name}.#{current.foreign_key}" + joins << "LEFT JOIN #{current.table_name} AS #{curr_table_name} ON #{curr_table_name}.#{relationship_primary_key} = #{prev_table_name}.#{current.foreign_key}" else - joins << "LEFT JOIN #{current.table_name} AS #{curr_table_name} ON #{curr_table_name}.#{current.foreign_key} = #{prev_table_name}.id" + joins << "LEFT JOIN #{current.table_name} AS #{curr_table_name} ON #{curr_table_name}.#{current.foreign_key} = #{prev_table_name}.#{relationship_primary_key}" end current diff --git a/test/controllers/widget_controller_test.rb b/test/controllers/widget_controller_test.rb new file mode 100644 index 000000000..6edfaee01 --- /dev/null +++ b/test/controllers/widget_controller_test.rb @@ -0,0 +1,47 @@ +require File.expand_path('../../test_helper', __FILE__) + +def set_content_type_header! + @request.headers['Content-Type'] = JSONAPI::MEDIA_TYPE +end + +class WidgetsControllerTest < ActionController::TestCase + def teardown + Widget.delete_all + Indicator.delete_all + Agency.delete_all + end + + def test_fetch_widgets_sort_by_agency_name + agency_1 = Agency.create! name: 'beta' + agency_2 = Agency.create! name: 'alpha' + indicator_1 = Indicator.create! import_id: 'foobar', name: 'bar', agency: agency_1 + indicator_2 = Indicator.create! import_id: 'foobar2', name: 'foo', agency: agency_2 + Widget.create! name: 'bar', indicator: indicator_1 + widget = Widget.create! name: 'foo', indicator: indicator_2 + assert_cacheable_get :index, params: {sort: 'indicator.agency.name'} + assert_response :success + assert_equal widget.id.to_s, json_response['data'].first['id'] + end +end + +class IndicatorsControllerTest < ActionController::TestCase + def teardown + Widget.delete_all + Indicator.delete_all + Agency.delete_all + end + + def test_fetch_indicators_sort_by_widgets_name + agency = Agency.create! name: 'test' + indicator_1 = Indicator.create! import_id: 'bar', name: 'bar', agency: agency + indicator_2 = Indicator.create! import_id: 'foo', name: 'foo', agency: agency + Widget.create! name: 'omega', indicator: indicator_1 + Widget.create! name: 'beta', indicator: indicator_1 + Widget.create! name: 'alpha', indicator: indicator_2 + Widget.create! name: 'zeta', indicator: indicator_2 + assert_cacheable_get :index, params: {sort: 'widgets.name'} + assert_response :success + assert_equal indicator_2.id.to_s, json_response['data'].first['id'] + assert_equal 2, json_response['data'].size + end +end diff --git a/test/fixtures/active_record.rb b/test/fixtures/active_record.rb index b5e3dc40b..f7f48b089 100644 --- a/test/fixtures/active_record.rb +++ b/test/fixtures/active_record.rb @@ -341,13 +341,14 @@ create_table :indicators, force: true do |t| t.string :name + t.string :import_id t.integer :agency_id, null: false t.timestamps null: false end create_table :widgets, force: true do |t| t.string :name - t.integer :indicator_id, null: false + t.string :indicator_import_id, null: false t.timestamps null: false end @@ -724,11 +725,11 @@ class Agency < ActiveRecord::Base class Indicator < ActiveRecord::Base belongs_to :agency - has_many :widgets + has_many :widgets, primary_key: :import_id, foreign_key: :indicator_import_id end class Widget < ActiveRecord::Base - belongs_to :indicator + belongs_to :indicator, primary_key: :import_id, foreign_key: :indicator_import_id end class Robot < ActiveRecord::Base @@ -2046,7 +2047,7 @@ class AgencyResource < JSONAPI::Resource class IndicatorResource < JSONAPI::Resource attributes :name has_one :agency - has_many :widgets + has_many :widgets, foreign_key: :indicator_import_id, primary_key: :import_id def self.sortable_fields(_context = nil) super + [:'widgets.name'] @@ -2055,7 +2056,7 @@ def self.sortable_fields(_context = nil) class WidgetResource < JSONAPI::Resource attributes :name - has_one :indicator + has_one :indicator, foreign_key: :indicator_import_id, primary_key: :import_id def self.sortable_fields(_context = nil) super + [:'indicator.agency.name'] diff --git a/test/unit/resource/active_relation_resource_finder_test.rb b/test/unit/resource/active_relation_resource_finder_test.rb index 228103689..b0d8afdaf 100644 --- a/test/unit/resource/active_relation_resource_finder_test.rb +++ b/test/unit/resource/active_relation_resource_finder_test.rb @@ -4,7 +4,7 @@ class ARPostResource < JSONAPI::Resource model_name 'Post' attribute :headline, delegate: :title has_one :author - has_many :tags + has_many :tags, primary_key: :tags_import_id end class ActiveRelationResourceFinderTest < ActiveSupport::TestCase