Skip to content

Commit 23bbe90

Browse files
committed
Run the bug
1 parent 5517f17 commit 23bbe90

File tree

4 files changed

+153
-7
lines changed

4 files changed

+153
-7
lines changed

Diff for: lib/jsonapi/relationship.rb

+38-7
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,48 @@ def table_name
5858
end
5959

6060
def self.polymorphic_types(name)
61+
polymorphic_types_lookup[name.to_sym]
62+
end
63+
64+
def self.polymorphic_types_lookup(warn_on_no_name: false)
6165
@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
66+
build_active_record_polymorphic_types_lookup(hash, warn_on_no_name: warn_on_no_name)
67+
end
68+
end
69+
70+
def self.build_active_record_polymorphic_types_lookup(hash, warn_on_no_name: false)
71+
candidate_active_record_polymorphic_classes.each do |klass|
72+
if klass.name.nil?
73+
if warn_on_no_name
74+
model_name =
75+
if klass.respond_to?(:model_name)
76+
begin
77+
klass.model_name.name
78+
rescue ArgumentError => e
79+
"Responds to ActiveModel::Naming but #{e.message}"
80+
end
81+
else
82+
"Does not extend ActiveModel::Naming"
83+
end
84+
warn "No class name found for #{klass} (#{model_name})"
6885
end
86+
next
87+
end
88+
klass.reflect_on_all_associations(:has_many).select{|r| r.options[:as] }.each do |reflection|
89+
(hash[reflection.options[:as]] ||= []) << klass.name.downcase
90+
end
91+
end
92+
end
93+
94+
def self.candidate_active_record_polymorphic_classes
95+
candidate_polymorphic_classes = []
96+
ObjectSpace.each_object do |klass|
97+
next unless Module === klass
98+
if ActiveRecord::Base > klass
99+
candidate_polymorphic_classes << klass
69100
end
70101
end
71-
@poly_hash[name.to_sym]
102+
candidate_polymorphic_classes
72103
end
73104

74105
def resource_types

Diff for: test/bug_1305_test.rb

+42
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

Diff for: test/fixtures/active_record.rb

+59
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'))

Diff for: test/test_helper.rb

+14
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@
4646
ActiveSupport::Deprecation.silenced = true
4747

4848
puts "Testing With RAILS VERSION #{Rails.version}"
49+
Minitest.after_run do
50+
puts "Found JSONAPI::Relationship.polymorphic_types_lookup"
51+
puts "\t #{JSONAPI::Relationship.polymorphic_types_lookup(warn_on_no_name: true).inspect}\n"
52+
end
4953

5054
class TestApp < Rails::Application
5155
config.eager_load = false
@@ -450,6 +454,16 @@ class CatResource < JSONAPI::Resource
450454

451455
mount MyEngine::Engine => "/boomshaka", as: :my_engine
452456
mount ApiV2Engine::Engine => "/api_v2", as: :api_v2_engine
457+
458+
jsonapi_resources :contact_media do
459+
jsonapi_relationships
460+
end
461+
jsonapi_resources :individuals do
462+
jsonapi_relationships
463+
end
464+
jsonapi_resources :organizations do
465+
jsonapi_relationships
466+
end
453467
end
454468

455469
MyEngine::Engine.routes.draw do

0 commit comments

Comments
 (0)