Skip to content

Commit b8e5d31

Browse files
Corrected apply_filters for non-belongs_to singular associations, and has_many associations with non-standard foreign table names
1 parent 7b3cdff commit b8e5d31

7 files changed

Lines changed: 39 additions & 23 deletions

File tree

lib/jsonapi/relationship.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ def resource_klass
2525
@resource_klass = @parent_resource.resource_for(@class_name)
2626
end
2727

28+
def table_name
29+
@table_name ||= resource_klass._table_name
30+
end
31+
2832
def relation_name(options)
2933
case @relation_name
3034
when Symbol
@@ -47,6 +51,10 @@ def type_for_source(source)
4751
end
4852
end
4953

54+
def belongs_to?
55+
false
56+
end
57+
5058
class ToOne < Relationship
5159
attr_reader :foreign_key_on
5260

lib/jsonapi/resource.rb

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -523,11 +523,11 @@ def apply_filters(records, filters, options = {})
523523
if filters
524524
filters.each do |filter, value|
525525
if _relationships.include?(filter)
526-
if _relationships[filter].is_a?(JSONAPI::Relationship::ToMany)
527-
required_includes.push(filter.to_s)
528-
records = apply_filter(records, "#{filter}.#{_relationships[filter].primary_key}", value, options)
526+
if _relationships[filter].belongs_to?
527+
records = apply_filter(records, _relationships[filter].foreign_key, value, options)
529528
else
530-
records = apply_filter(records, "#{_relationships[filter].foreign_key}", value, options)
529+
required_includes.push(filter.to_s)
530+
records = apply_filter(records, "#{_relationships[filter].table_name}.#{_relationships[filter].primary_key}", value, options)
531531
end
532532
else
533533
records = apply_filter(records, filter, value, options)
@@ -696,6 +696,10 @@ def _primary_key
696696
@_primary_key ||= _model_class.respond_to?(:primary_key) ? _model_class.primary_key : :id
697697
end
698698

699+
def _table_name
700+
@_table_name ||= _model_class.respond_to?(:table_name) ? _model_class.table_name : _model_name.tableize
701+
end
702+
699703
def _as_parent_key
700704
@_as_parent_key ||= "#{_type.to_s.singularize}_id"
701705
end

test/fixtures/active_record.rb

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -368,8 +368,7 @@ class Crater < ActiveRecord::Base
368368
end
369369

370370
class Preferences < ActiveRecord::Base
371-
has_one :author, class_name: 'Person'
372-
has_many :friends, class_name: 'Person'
371+
has_one :author, class_name: 'Person', :inverse_of => 'preferences'
373372
end
374373

375374
class Fact < ActiveRecord::Base
@@ -979,9 +978,6 @@ class EmployeeResource < JSONAPI::Resource
979978
model_name 'Person'
980979
end
981980

982-
class FriendResource < JSONAPI::Resource
983-
end
984-
985981
class BreedResource < JSONAPI::Resource
986982
attribute :name, format: :title
987983

@@ -1053,8 +1049,7 @@ def self.verify_key(key, context = nil)
10531049
class PreferencesResource < JSONAPI::Resource
10541050
attribute :advanced_mode
10551051

1056-
has_one :author, foreign_key: :person_id
1057-
has_many :friends
1052+
has_one :author, :foreign_key_on => :related
10581053

10591054
def self.find_by_key(key, options = {})
10601055
new(Preferences.first, nil)
@@ -1164,7 +1159,6 @@ class MoonResource < MoonResource; end
11641159
class CraterResource < CraterResource; end
11651160
class PreferencesResource < PreferencesResource; end
11661161
class EmployeeResource < EmployeeResource; end
1167-
class FriendResource < FriendResource; end
11681162
class HairCutResource < HairCutResource; end
11691163
class VehicleResource < VehicleResource; end
11701164
class CarResource < CarResource; end

test/fixtures/comments.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ post_2_thanks_man:
1818

1919
rogue_comment:
2020
body: Rogue Comment Here
21-
author_id: 3
21+
author_id: 3

test/fixtures/preferences.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
a:
22
id: 1
3-
person_id:
43
advanced_mode: false
54

65
b:
76
id: 2
8-
person_id:
97
advanced_mode: false
108
c:
119
id: 3
12-
person_id:
1310
advanced_mode: false
1411

1512
d:
1613
id: 4
17-
person_id:
1814
advanced_mode: false

test/unit/resource/resource_test.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,26 @@ def test_createable_fields_delegates_to_creatable_fields_with_deprecation
264264
end
265265
end
266266

267+
def test_filter_on_to_many_relationship_id
268+
posts = PostResource.find(:comments => 3)
269+
assert_equal([2], posts.map(&:id))
270+
end
271+
272+
def test_filter_on_aliased_to_many_relationship_id
273+
# Comment 2 is approved
274+
books = Api::V2::BookResource.find(:aliased_comments => 2)
275+
assert_equal([0], books.map(&:id))
276+
277+
# However, comment 3 is non-approved, so it won't be accessible through this relationship
278+
books = Api::V2::BookResource.find(:aliased_comments => 3)
279+
assert_equal([], books.map(&:id))
280+
end
281+
282+
def test_filter_on_has_one_relationship_id
283+
people = PreferencesResource.find(:author => 1)
284+
assert_equal([1], people.map(&:id))
285+
end
286+
267287
def test_to_many_relationship_filters
268288
post_resource = PostResource.new(Post.find(1), nil)
269289
comments = post_resource.comments

test/unit/serializer/serializer_test.rb

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1638,12 +1638,6 @@ def test_serializer_booleans
16381638
self: '/preferences/1/relationships/author',
16391639
related: '/preferences/1/author'
16401640
}
1641-
},
1642-
friends: {
1643-
links: {
1644-
self: '/preferences/1/relationships/friends',
1645-
related: '/preferences/1/friends'
1646-
}
16471641
}
16481642
}
16491643
}

0 commit comments

Comments
 (0)