Skip to content

Commit

Permalink
Polymorphic types override per relationship (#1440)
Browse files Browse the repository at this point in the history
* Add warning about disabling eager loading

* Fix overriding polymorphic types on a relationship
  • Loading branch information
lgebhardt authored Jan 26, 2024
1 parent c529c23 commit f75acdb
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 18 deletions.
4 changes: 2 additions & 2 deletions lib/jsonapi/active_relation_retrieval.rb
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ def find_fragments(filters, options = {})
def find_related_fragments(source_fragment, relationship, options = {})
if relationship.polymorphic? # && relationship.foreign_key_on == :self
source_resource_klasses = if relationship.foreign_key_on == :self
relationship.class.polymorphic_types(relationship.name).collect do |polymorphic_type|
relationship.polymorphic_types.collect do |polymorphic_type|
resource_klass_for(polymorphic_type)
end
else
Expand All @@ -284,7 +284,7 @@ def find_related_fragments(source_fragment, relationship, options = {})
def find_included_fragments(source_fragments, relationship, options)
if relationship.polymorphic? # && relationship.foreign_key_on == :self
source_resource_klasses = if relationship.foreign_key_on == :self
relationship.class.polymorphic_types(relationship.name).collect do |polymorphic_type|
relationship.polymorphic_types.collect do |polymorphic_type|
resource_klass_for(polymorphic_type)
end
else
Expand Down
4 changes: 4 additions & 0 deletions lib/jsonapi/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class Configuration
:warn_on_route_setup_issues,
:warn_on_missing_routes,
:warn_on_performance_issues,
:warn_on_eager_loading_disabled,
:default_allow_include_to_one,
:default_allow_include_to_many,
:allow_sort,
Expand Down Expand Up @@ -67,6 +68,7 @@ def initialize
self.warn_on_route_setup_issues = true
self.warn_on_missing_routes = true
self.warn_on_performance_issues = true
self.warn_on_eager_loading_disabled = true

# :none, :offset, :paged, or a custom paginator name
self.default_paginator = :none
Expand Down Expand Up @@ -326,6 +328,8 @@ def allow_include=(allow_include)

attr_writer :warn_on_performance_issues

attr_writer :warn_on_eager_loading_disabled

attr_writer :use_relationship_reflection

attr_writer :resource_cache
Expand Down
36 changes: 22 additions & 14 deletions lib/jsonapi/relationship.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ def initialize(name, options = {})
@parent_resource = options[:parent_resource]
@relation_name = options[:relation_name]
@polymorphic = options.fetch(:polymorphic, false) == true
@polymorphic_types = options[:polymorphic_types]
@polymorphic_types_override = options[:polymorphic_types]

if options[:polymorphic_relations]
JSONAPI.configuration.deprecate('Use polymorphic_types instead of polymorphic_relations')
@polymorphic_types ||= options[:polymorphic_relations]
@polymorphic_types_override ||= options[:polymorphic_relations]
end

use_related_resource_records_for_joins_default = if options[:relation_name]
Expand Down Expand Up @@ -86,16 +87,27 @@ def inverse_relationship
@inverse_relationship
end

def self.polymorphic_types(name)
::JSONAPI::Utils::PolymorphicTypesLookup.polymorphic_types(name)
def polymorphic_types
return @polymorphic_types if @polymorphic_types

types = @polymorphic_types_override
types ||= ::JSONAPI::Utils::PolymorphicTypesLookup.polymorphic_types(_relation_name)

@polymorphic_types = types&.map { |t| t.to_s.pluralize } || []

if @polymorphic_types.blank?
warn "[POLYMORPHIC TYPE] No polymorphic types set or found for #{parent_resource.name} #{_relation_name}"
end

@polymorphic_types
end

def resource_types
if polymorphic? && belongs_to?
@polymorphic_types ||= self.class.polymorphic_types(_relation_name).collect { |t| t.pluralize }
else
[resource_klass._type.to_s.pluralize]
end
@resource_types ||= if polymorphic?
polymorphic_types
else
[resource_klass._type.to_s.pluralize]
end
end

def type
Expand Down Expand Up @@ -191,11 +203,7 @@ def polymorphic_type
end

def setup_implicit_relationships_for_polymorphic_types(exclude_linkage_data: true)
types = self.class.polymorphic_types(_relation_name)
unless types.present?
warn "[POLYMORPHIC TYPE] No polymorphic types found for #{parent_resource.name} #{_relation_name}"
return
end
types = polymorphic_types

types.each do |type|
parent_resource.has_one(type.to_s.underscore.singularize,
Expand Down
8 changes: 6 additions & 2 deletions lib/jsonapi/resources/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@ class Railtie < ::Rails::Railtie
}
end

initializer "jsonapi_resources.initialize", after: :initialize do
JSONAPI::Utils::PolymorphicTypesLookup.polymorphic_types_lookup_clear!
config.before_initialize do
if !Rails.application.config.eager_load && ::JSONAPI::configuration.warn_on_eager_loading_disabled
warn 'WARNING: jsonapi-resources may not load polymorphic types when Rails `eager_load` is disabled. ' \
'Polymorphic types may be set per relationship . This warning may be disable in the configuration ' \
'by setting `warn_on_eager_loading_disabled` to false.'
end
end
end
end
Expand Down

0 comments on commit f75acdb

Please sign in to comment.