Skip to content

Commit

Permalink
Run the bug
Browse files Browse the repository at this point in the history
  • Loading branch information
bf4 committed Jan 12, 2021
1 parent 5517f17 commit 4a86c4f
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 7 deletions.
45 changes: 38 additions & 7 deletions lib/jsonapi/relationship.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,48 @@ def table_name
end

def self.polymorphic_types(name)
polymorphic_types_lookup[name.to_sym]
end

def self.polymorphic_types_lookup(warn_on_no_name: false)
@poly_hash ||= {}.tap do |hash|
ObjectSpace.each_object do |klass|
next unless Module === klass
if ActiveRecord::Base > klass
klass.reflect_on_all_associations(:has_many).select{|r| r.options[:as] }.each do |reflection|
(hash[reflection.options[:as]] ||= []) << klass.name.downcase
end
build_active_record_polymorphic_types_lookup(hash, warn_on_no_name: warn_on_no_name)
end
end

def self.build_active_record_polymorphic_types_lookup(hash, warn_on_no_name: false)
candidate_active_record_polymorphic_classes.each do |klass|
if klass.name.nil?
if warn_on_no_name
model_name =
if klass.respond_to?(:model_name)
begin
klass.model_name.name
rescue ArgumentError => e
"Responds to ActiveModel::Naming but #{e.message}"
end
else
"Does not extend ActiveModel::Naming"
end
warn "No class name found for #{klass} (#{model_name})"
end
next
end
klass.reflect_on_all_associations(:has_many).select{|r| r.options[:as] }.each do |reflection|
(hash[reflection.options[:as]] ||= []) << klass.name.downcase
end
end
end

def self.candidate_active_record_polymorphic_classes
candidate_polymorphic_classes = []
ObjectSpace.each_object do |klass|
next unless Module === klass
if ActiveRecord::Base > klass
candidate_polymorphic_classes << klass
end
end
@poly_hash[name.to_sym]
candidate_polymorphic_classes
end

def resource_types
Expand Down
44 changes: 44 additions & 0 deletions test/bug_1305_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require File.expand_path('../test_helper', __FILE__)

# Replace this with the code necessary to make your test fail.
class BugTest < Minitest::Test
include Rack::Test::Methods

def json_api_headers
{'Accept' => JSONAPI::MEDIA_TYPE, 'CONTENT_TYPE' => JSONAPI::MEDIA_TYPE}
end

def teardown
Individual.delete_all
ContactMedium.delete_all
end

def test_find_party_via_contact_medium
individual = Individual.create(name: 'test')
contact_medium = ContactMedium.create(party: individual, name: 'test contact medium')
fetched_party = contact_medium.party
assert_same individual, fetched_party, "Expect an individual to have been found via contact medium model's relationship 'party'"
end

def test_get_individual
individual = Individual.create(name: 'test')
ContactMedium.create(party: individual, name: 'test contact medium')
get "/individuals/#{individual.id}"
assert last_response.ok?
end

def test_get_party_via_contact_medium
individual = Individual.create(name: 'test')
contact_medium = ContactMedium.create(party: individual, name: 'test contact medium')
get "/contact_media/#{contact_medium.id}/party"
# pp [:last_response, last_response]
# ["{\"errors\":[{\"title\":\"Internal Server Error\",\"detail\":\"Internal Server Error\",\"code\":\"500\",\"status\":\"500\",\"meta\":{\"exception\":\"Can't join 'ContactMedium' to association named 'organization'; perhaps you misspelled it?\"
assert last_response.ok?, "Expect an individual to have been found via contact medium resource's relationship 'party'"
end

private

def app
Rails.application
end
end
59 changes: 59 additions & 0 deletions test/fixtures/active_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,19 @@
t.integer :version
t.timestamps null: false
end

create_table :contact_media do |t|
t.string :name
t.references :party, polymorphic: true, index: true
end

create_table :individuals do |t|
t.string :name
end

create_table :organizations do |t|
t.string :name
end
end

### MODELS
Expand Down Expand Up @@ -643,6 +656,22 @@ class Fact < ActiveRecord::Base
class Like < ActiveRecord::Base
end

class TestApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end

class ContactMedium < TestApplicationRecord
belongs_to :party, polymorphic: true, inverse_of: :contact_media
end

class Individual < TestApplicationRecord
has_many :contact_media, as: :party
end

class Organization < TestApplicationRecord
has_many :contact_media, as: :party
end

class Breed
include ActiveModel::Model

Expand Down Expand Up @@ -1246,6 +1275,18 @@ class IndicatorsController < JSONAPI::ResourceController
class RobotsController < JSONAPI::ResourceController
end

class IndividualsController < BaseController
end

class OrganizationsController < BaseController
end

class ContactMediaController < BaseController
end

class PartiesController < BaseController
end

### RESOURCES
class BaseResource < JSONAPI::Resource
abstract
Expand Down Expand Up @@ -2688,6 +2729,24 @@ class RobotResource < ::JSONAPI::Resource
end
end

class ContactMediumResource < JSONAPI::Resource
attribute :name
has_one :party, polymorphic: true
end

class IndividualResource < JSONAPI::Resource
attribute :name
has_many :contact_media
end

class OrganizationResource < JSONAPI::Resource
attribute :name
has_many :contact_media
end

class PartyResource < JSONAPI::Resource
end

### PORO Data - don't do this in a production app
$breed_data = BreedData.new
$breed_data.add(Breed.new(0, 'persian'))
Expand Down
14 changes: 14 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
ActiveSupport::Deprecation.silenced = true

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

class TestApp < Rails::Application
config.eager_load = false
Expand Down Expand Up @@ -450,6 +454,16 @@ class CatResource < JSONAPI::Resource

mount MyEngine::Engine => "/boomshaka", as: :my_engine
mount ApiV2Engine::Engine => "/api_v2", as: :api_v2_engine

jsonapi_resources :contact_media do
jsonapi_relationships
end
jsonapi_resources :individuals do
jsonapi_relationships
end
jsonapi_resources :organizations do
jsonapi_relationships
end
end

MyEngine::Engine.routes.draw do
Expand Down

0 comments on commit 4a86c4f

Please sign in to comment.