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 11, 2021
1 parent 5517f17 commit d90f30e
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 6 deletions.
34 changes: 28 additions & 6 deletions lib/jsonapi/relationship.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,40 @@ def table_name

def self.polymorphic_types(name)
@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
candidate_polymorphic_classes.each do |klass|
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
@poly_hash[name.to_sym]
end

def self.candidate_polymorphic_classes
candidate_polymorphic_classes = []
ObjectSpace.each_object do |klass|
next unless Module === klass
if ActiveRecord::Base > klass
if !klass.name.nil?
candidate_polymorphic_classes << klass
else
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
end
end
candidate_polymorphic_classes
end

def resource_types
if polymorphic? && belongs_to?
@polymorphic_types ||= self.class.polymorphic_types(@relation_name).collect {|t| t.pluralize}
Expand Down
42 changes: 42 additions & 0 deletions test/bug-1305.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
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"
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
10 changes: 10 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,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 d90f30e

Please sign in to comment.