diff --git a/lib/jsonapi/configuration.rb b/lib/jsonapi/configuration.rb index 69e253161..2cf5e2501 100644 --- a/lib/jsonapi/configuration.rb +++ b/lib/jsonapi/configuration.rb @@ -33,7 +33,8 @@ class Configuration :resource_cache, :default_resource_cache_field, :resource_cache_digest_function, - :resource_cache_usage_report_function + :resource_cache_usage_report_function, + :default_exclude_links def initialize #:underscored_key, :camelized_key, :dasherized_key, or custom @@ -134,6 +135,12 @@ def initialize # Optionally provide a callable which JSONAPI will call with information about cache # performance. Should accept three arguments: resource name, hits count, misses count. self.resource_cache_usage_report_function = nil + + # Global configuration for links exclusion + # Controls whether to generate links like `self`, `related` with all the resources + # and relationships. Accepts either `:default`, `:none`, or array containing the + # specific default links to exclude, which may be `:self` and `:related`. + self.default_exclude_links = :none end def cache_formatters=(bool) @@ -249,6 +256,8 @@ def default_processor_klass=(default_processor_klass) attr_writer :resource_cache_digest_function attr_writer :resource_cache_usage_report_function + + attr_writer :default_exclude_links end class << self diff --git a/lib/jsonapi/relationship.rb b/lib/jsonapi/relationship.rb index 8f17658df..398728fb0 100644 --- a/lib/jsonapi/relationship.rb +++ b/lib/jsonapi/relationship.rb @@ -16,11 +16,10 @@ def initialize(name, options = {}) @polymorphic = options.fetch(:polymorphic, false) == true @always_include_linkage_data = options.fetch(:always_include_linkage_data, false) == true @eager_load_on_include = options.fetch(:eager_load_on_include, true) == true - @_routed = false @_warned_missing_route = false - exclude_links(options.fetch(:exclude_links, :none)) + exclude_links(options.fetch(:exclude_links, JSONAPI.configuration.default_exclude_links)) end alias_method :polymorphic?, :polymorphic diff --git a/lib/jsonapi/resource.rb b/lib/jsonapi/resource.rb index fc288a96b..90b6f5baf 100644 --- a/lib/jsonapi/resource.rb +++ b/lib/jsonapi/resource.rb @@ -1069,6 +1069,18 @@ def mutable? end def exclude_links(exclude) + _resolve_exclude_links(exclude) + end + + def _exclude_links + @_exclude_links ||= _resolve_exclude_links(JSONAPI.configuration.default_exclude_links) + end + + def exclude_link?(link) + _exclude_links.include?(link.to_sym) + end + + def _resolve_exclude_links(exclude) case exclude when :default, "default" @_exclude_links = [:self] @@ -1081,14 +1093,6 @@ def exclude_links(exclude) end end - def _exclude_links - @_exclude_links ||= [] - end - - def exclude_link?(link) - _exclude_links.include?(link.to_sym) - end - def caching(val = true) @caching = val end diff --git a/test/unit/resource/relationship_test.rb b/test/unit/resource/relationship_test.rb index bdf897e7b..74791d8f3 100644 --- a/test/unit/resource/relationship_test.rb +++ b/test/unit/resource/relationship_test.rb @@ -9,6 +9,88 @@ def test_polymorphic_type assert_equal(relationship.polymorphic_type, "imageable_type") end + def test_global_exclude_links_configuration_on_relationship + JSONAPI.configuration.default_exclude_links = :none + relationship = JSONAPI::Relationship::ToOne.new "foo" + assert_equal [], relationship._exclude_links + refute relationship.exclude_link?(:self) + refute relationship.exclude_link?("self") + + JSONAPI.configuration.default_exclude_links = :default + relationship = JSONAPI::Relationship::ToOne.new "foo" + assert_equal [:self, :related], relationship._exclude_links + assert relationship.exclude_link?(:self) + assert relationship.exclude_link?("self") + assert relationship.exclude_link?(:related) + assert relationship.exclude_link?("related") + + JSONAPI.configuration.default_exclude_links = "none" + relationship = JSONAPI::Relationship::ToOne.new "foo" + assert_equal [], relationship._exclude_links + refute relationship.exclude_link?(:self) + refute relationship.exclude_link?("self") + + JSONAPI.configuration.default_exclude_links = "default" + relationship = JSONAPI::Relationship::ToOne.new "foo" + assert_equal [:self, :related], relationship._exclude_links + assert relationship.exclude_link?(:self) + assert relationship.exclude_link?("self") + + JSONAPI.configuration.default_exclude_links = :none + relationship = JSONAPI::Relationship::ToOne.new "foo" + assert_equal [], relationship._exclude_links + refute relationship.exclude_link?(:self) + refute relationship.exclude_link?("self") + + JSONAPI.configuration.default_exclude_links = [:self] + relationship = JSONAPI::Relationship::ToOne.new "foo" + assert_equal [:self], relationship._exclude_links + assert relationship.exclude_link?(:self) + assert relationship.exclude_link?("self") + + JSONAPI.configuration.default_exclude_links = :none + relationship = JSONAPI::Relationship::ToOne.new "foo" + assert_equal [], relationship._exclude_links + refute relationship.exclude_link?(:self) + refute relationship.exclude_link?("self") + + JSONAPI.configuration.default_exclude_links = ["self", :related] + relationship = JSONAPI::Relationship::ToOne.new "foo" + assert_equal [:self, :related], relationship._exclude_links + assert relationship.exclude_link?(:self) + assert relationship.exclude_link?("self") + + JSONAPI.configuration.default_exclude_links = [] + relationship = JSONAPI::Relationship::ToOne.new "foo" + assert_equal [], relationship._exclude_links + refute relationship.exclude_link?(:self) + refute relationship.exclude_link?("self") + + assert_raises do + JSONAPI.configuration.default_exclude_links = :self + JSONAPI::Relationship::ToOne.new "foo" + end + + # Test if the relationships will override the the global configuration + JSONAPI.configuration.default_exclude_links = :default + relationship = JSONAPI::Relationship::ToOne.new "foo", exclude_links: :none + assert_equal [], relationship._exclude_links + refute relationship.exclude_link?(:self) + refute relationship.exclude_link?("self") + refute relationship.exclude_link?(:related) + refute relationship.exclude_link?("related") + + JSONAPI.configuration.default_exclude_links = :default + relationship = JSONAPI::Relationship::ToOne.new "foo", exclude_links: [:self] + assert_equal [:self], relationship._exclude_links + refute relationship.exclude_link?(:related) + refute relationship.exclude_link?("related") + assert relationship.exclude_link?(:self) + assert relationship.exclude_link?("self") + ensure + JSONAPI.configuration.default_exclude_links = :none + end + def test_exclude_links_on_relationship relationship = JSONAPI::Relationship::ToOne.new "foo", exclude_links: :none assert_equal [], relationship._exclude_links