Skip to content

Commit d90f30e

Browse files
committed
Run the bug
1 parent 5517f17 commit d90f30e

File tree

4 files changed

+139
-6
lines changed

4 files changed

+139
-6
lines changed

lib/jsonapi/relationship.rb

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,40 @@ def table_name
5959

6060
def self.polymorphic_types(name)
6161
@poly_hash ||= {}.tap do |hash|
62-
ObjectSpace.each_object do |klass|
63-
next unless Module === klass
64-
if ActiveRecord::Base > klass
65-
klass.reflect_on_all_associations(:has_many).select{|r| r.options[:as] }.each do |reflection|
66-
(hash[reflection.options[:as]] ||= []) << klass.name.downcase
67-
end
62+
candidate_polymorphic_classes.each do |klass|
63+
klass.reflect_on_all_associations(:has_many).select{|r| r.options[:as] }.each do |reflection|
64+
(hash[reflection.options[:as]] ||= []) << klass.name.downcase
6865
end
6966
end
7067
end
7168
@poly_hash[name.to_sym]
7269
end
7370

71+
def self.candidate_polymorphic_classes
72+
candidate_polymorphic_classes = []
73+
ObjectSpace.each_object do |klass|
74+
next unless Module === klass
75+
if ActiveRecord::Base > klass
76+
if !klass.name.nil?
77+
candidate_polymorphic_classes << klass
78+
else
79+
model_name =
80+
if klass.respond_to?(:model_name)
81+
begin
82+
klass.model_name.name
83+
rescue ArgumentError => e
84+
"Responds to ActiveModel::Naming but #{e.message}"
85+
end
86+
else
87+
"Does not extend ActiveModel::Naming"
88+
end
89+
warn "No class name found for #{klass} (#{model_name})"
90+
end
91+
end
92+
end
93+
candidate_polymorphic_classes
94+
end
95+
7496
def resource_types
7597
if polymorphic? && belongs_to?
7698
@polymorphic_types ||= self.class.polymorphic_types(@relation_name).collect {|t| t.pluralize}

test/bug-1305.rb

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
require File.expand_path('../test_helper', __FILE__)
2+
3+
# Replace this with the code necessary to make your test fail.
4+
class BugTest < Minitest::Test
5+
include Rack::Test::Methods
6+
7+
def json_api_headers
8+
{'Accept' => JSONAPI::MEDIA_TYPE, 'CONTENT_TYPE' => JSONAPI::MEDIA_TYPE}
9+
end
10+
11+
def teardown
12+
Individual.delete_all
13+
ContactMedium.delete_all
14+
end
15+
16+
def test_find_party_via_contact_medium
17+
individual = Individual.create(name: 'test')
18+
contact_medium = ContactMedium.create(party: individual, name: 'test contact medium')
19+
fetched_party = contact_medium.party
20+
assert_same individual, fetched_party, "Expect an individual to have been found via contact medium model's relationship 'party'"
21+
end
22+
23+
def test_get_individual
24+
individual = Individual.create(name: 'test')
25+
ContactMedium.create(party: individual, name: 'test contact medium')
26+
get "/individuals/#{individual.id}"
27+
assert last_response.ok?
28+
end
29+
30+
def test_get_party_via_contact_medium
31+
individual = Individual.create(name: 'test')
32+
contact_medium = ContactMedium.create(party: individual, name: 'test contact medium')
33+
get "/contact_media/#{contact_medium.id}/party"
34+
assert last_response.ok?, "Expect an individual to have been found via contact medium resource's relationship 'party'"
35+
end
36+
37+
private
38+
39+
def app
40+
Rails.application
41+
end
42+
end

test/fixtures/active_record.rb

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,19 @@
429429
t.integer :version
430430
t.timestamps null: false
431431
end
432+
433+
create_table :contact_media do |t|
434+
t.string :name
435+
t.references :party, polymorphic: true, index: true
436+
end
437+
438+
create_table :individuals do |t|
439+
t.string :name
440+
end
441+
442+
create_table :organizations do |t|
443+
t.string :name
444+
end
432445
end
433446

434447
### MODELS
@@ -643,6 +656,22 @@ class Fact < ActiveRecord::Base
643656
class Like < ActiveRecord::Base
644657
end
645658

659+
class TestApplicationRecord < ActiveRecord::Base
660+
self.abstract_class = true
661+
end
662+
663+
class ContactMedium < TestApplicationRecord
664+
belongs_to :party, polymorphic: true, inverse_of: :contact_media
665+
end
666+
667+
class Individual < TestApplicationRecord
668+
has_many :contact_media, as: :party
669+
end
670+
671+
class Organization < TestApplicationRecord
672+
has_many :contact_media, as: :party
673+
end
674+
646675
class Breed
647676
include ActiveModel::Model
648677

@@ -1246,6 +1275,18 @@ class IndicatorsController < JSONAPI::ResourceController
12461275
class RobotsController < JSONAPI::ResourceController
12471276
end
12481277

1278+
class IndividualsController < BaseController
1279+
end
1280+
1281+
class OrganizationsController < BaseController
1282+
end
1283+
1284+
class ContactMediaController < BaseController
1285+
end
1286+
1287+
class PartiesController < BaseController
1288+
end
1289+
12491290
### RESOURCES
12501291
class BaseResource < JSONAPI::Resource
12511292
abstract
@@ -2688,6 +2729,24 @@ class RobotResource < ::JSONAPI::Resource
26882729
end
26892730
end
26902731

2732+
class ContactMediumResource < JSONAPI::Resource
2733+
attribute :name
2734+
has_one :party, polymorphic: true
2735+
end
2736+
2737+
class IndividualResource < JSONAPI::Resource
2738+
attribute :name
2739+
has_many :contact_media
2740+
end
2741+
2742+
class OrganizationResource < JSONAPI::Resource
2743+
attribute :name
2744+
has_many :contact_media
2745+
end
2746+
2747+
class PartyResource < JSONAPI::Resource
2748+
end
2749+
26912750
### PORO Data - don't do this in a production app
26922751
$breed_data = BreedData.new
26932752
$breed_data.add(Breed.new(0, 'persian'))

test/test_helper.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,16 @@ class CatResource < JSONAPI::Resource
450450

451451
mount MyEngine::Engine => "/boomshaka", as: :my_engine
452452
mount ApiV2Engine::Engine => "/api_v2", as: :api_v2_engine
453+
454+
jsonapi_resources :contact_media do
455+
jsonapi_relationships
456+
end
457+
jsonapi_resources :individuals do
458+
jsonapi_relationships
459+
end
460+
jsonapi_resources :organizations do
461+
jsonapi_relationships
462+
end
453463
end
454464

455465
MyEngine::Engine.routes.draw do

0 commit comments

Comments
 (0)