Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ platforms :ruby do

if version.start_with?('4.2', '5.0')
gem 'sqlite3', '~> 1.3.13'
elsif version.start_with?('8.')
# Rails 8.0+ requires sqlite3 >= 2.1
gem 'sqlite3', '>= 2.1'
else
gem 'sqlite3', '~> 1.4'
end
Expand Down
8 changes: 4 additions & 4 deletions lib/jsonapi/acts_as_resource_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,16 @@ def index_related_resources

def get_related_resource
# :nocov:
ActiveSupport::Deprecation.warn "In #{self.class.name} you exposed a `get_related_resource`"\
" action. Please use `show_related_resource` instead."
JSONAPI.warn_deprecated "In #{self.class.name} you exposed a `get_related_resource`"\
" action. Please use `show_related_resource` instead."
show_related_resource
# :nocov:
end

def get_related_resources
# :nocov:
ActiveSupport::Deprecation.warn "In #{self.class.name} you exposed a `get_related_resources`"\
" action. Please use `index_related_resources` instead."
JSONAPI.warn_deprecated "In #{self.class.name} you exposed a `get_related_resources`"\
" action. Please use `index_related_resources` instead."
index_related_resources
# :nocov:
end
Expand Down
12 changes: 6 additions & 6 deletions lib/jsonapi/basic_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ def attribute(attribute_name, options = {})
check_reserved_attribute_name(attr)

if (attr == :id) && (options[:format].nil?)
ActiveSupport::Deprecation.warn('Id without format is no longer supported. Please remove ids from attributes, or specify a format.')
JSONAPI.warn_deprecated('Id without format is no longer supported. Please remove ids from attributes, or specify a format.')
end

check_duplicate_attribute_name(attr) if options[:format].nil?
Expand Down Expand Up @@ -609,11 +609,11 @@ def has_one(*attrs)
end

def belongs_to(*attrs)
ActiveSupport::Deprecation.warn "In #{name} you exposed a `has_one` relationship "\
" using the `belongs_to` class method. We think `has_one`" \
" is more appropriate. If you know what you're doing," \
" and don't want to see this warning again, override the" \
" `belongs_to` class method on your resource."
JSONAPI.warn_deprecated "In #{name} you exposed a `has_one` relationship "\
" using the `belongs_to` class method. We think `has_one`" \
" is more appropriate. If you know what you're doing," \
" and don't want to see this warning again, override the" \
" `belongs_to` class method on your resource."
_add_relationship(Relationship::ToOne, *attrs)
end

Expand Down
32 changes: 24 additions & 8 deletions lib/jsonapi/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ def exception_class_allowed?(e)
end

def default_processor_klass=(default_processor_klass)
ActiveSupport::Deprecation.warn('`default_processor_klass` has been replaced by `default_processor_klass_name`.')
JSONAPI.warn_deprecated('`default_processor_klass` has been replaced by `default_processor_klass_name`.')
@default_processor_klass = default_processor_klass
end

Expand All @@ -241,18 +241,18 @@ def default_processor_klass_name=(default_processor_klass_name)
end

def allow_include=(allow_include)
ActiveSupport::Deprecation.warn('`allow_include` has been replaced by `default_allow_include_to_one` and `default_allow_include_to_many` options.')
JSONAPI.warn_deprecated('`allow_include` has been replaced by `default_allow_include_to_one` and `default_allow_include_to_many` options.')
@default_allow_include_to_one = allow_include
@default_allow_include_to_many = allow_include
end

def whitelist_all_exceptions=(allow_all_exceptions)
ActiveSupport::Deprecation.warn('`whitelist_all_exceptions` has been replaced by `allow_all_exceptions`')
JSONAPI.warn_deprecated('`whitelist_all_exceptions` has been replaced by `allow_all_exceptions`')
@allow_all_exceptions = allow_all_exceptions
end

def exception_class_whitelist=(exception_class_allowlist)
ActiveSupport::Deprecation.warn('`exception_class_whitelist` has been replaced by `exception_class_allowlist`')
JSONAPI.warn_deprecated('`exception_class_whitelist` has been replaced by `exception_class_allowlist`')
@exception_class_allowlist = exception_class_allowlist
end

Expand Down Expand Up @@ -314,12 +314,28 @@ def exception_class_whitelist=(exception_class_allowlist)
end

class << self
attr_accessor :configuration
end
attr_writer :configuration

@configuration ||= Configuration.new
def configuration
@configuration ||= Configuration.new
end
end

def self.configure
yield(@configuration)
yield(configuration)
end

# Rails 7.2+ made ActiveSupport::Deprecation.warn a private method
# This helper provides backward-compatible deprecation warnings
def self.warn_deprecated(message)
if defined?(ActiveSupport::Deprecation) && ActiveSupport::Deprecation.respond_to?(:warn)
# Rails < 7.2
ActiveSupport::Deprecation.warn(message)
else
# Rails 7.2+ or fallback - use standard warning with deprecation formatting
# Rails 7.2 doesn't provide a public API for custom deprecation warnings
# So we use Kernel#warn with a deprecation prefix
warn "[DEPRECATION] #{message}"
end
end
end
24 changes: 22 additions & 2 deletions lib/jsonapi/error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@ module JSONAPI
class Error
attr_accessor :title, :detail, :id, :href, :code, :source, :links, :status, :meta

# Rack 3.0+ deprecated :unprocessable_entity in favor of :unprocessable_content
# This mapping ensures compatibility across Rack versions
DEPRECATED_STATUS_SYMBOLS = {
unprocessable_entity: :unprocessable_content
}.freeze

def self.status_code_for(status_symbol)
return nil if status_symbol.nil?

# Try the symbol directly first
code = Rack::Utils::SYMBOL_TO_STATUS_CODE[status_symbol]

# If not found and it's a deprecated symbol, try the new symbol
if code.nil? && DEPRECATED_STATUS_SYMBOLS.key?(status_symbol)
code = Rack::Utils::SYMBOL_TO_STATUS_CODE[DEPRECATED_STATUS_SYMBOLS[status_symbol]]
end

code&.to_s
end

def initialize(options = {})
@title = options[:title]
@detail = options[:detail]
Expand All @@ -17,7 +37,7 @@ def initialize(options = {})
@source = options[:source]
@links = options[:links]

@status = Rack::Utils::SYMBOL_TO_STATUS_CODE[options[:status]].to_s
@status = self.class.status_code_for(options[:status])
@meta = options[:meta]
end

Expand Down Expand Up @@ -48,7 +68,7 @@ def update_with_overrides(error_object_overrides)

if error_object_overrides[:status]
# :nocov:
@status = Rack::Utils::SYMBOL_TO_STATUS_CODE[error_object_overrides[:status]].to_s
@status = self.class.status_code_for(error_object_overrides[:status])
# :nocov:
end
@meta = error_object_overrides[:meta] || @meta
Expand Down
2 changes: 1 addition & 1 deletion lib/jsonapi/relationship.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def initialize(name, options = {})
@polymorphic = options.fetch(:polymorphic, false) == true
@polymorphic_types = options[:polymorphic_types]
if options[:polymorphic_relations]
ActiveSupport::Deprecation.warn('Use polymorphic_types instead of polymorphic_relations')
JSONAPI.warn_deprecated('Use polymorphic_types instead of polymorphic_relations')
@polymorphic_types ||= options[:polymorphic_relations]
end

Expand Down
38 changes: 31 additions & 7 deletions lib/jsonapi/routing_ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,30 @@ def jsonapi_resource(*resources, &_block)

resource @resource_type, options do
# :nocov:
if @scope.respond_to? :[]=
if @scope.respond_to?(:[]=)
# Rails 4
@scope[:jsonapi_resource] = @resource_type

if block_given?
yield
else
jsonapi_relationships
end
elsif Rails::VERSION::MAJOR >= 8 && Rails::VERSION::MINOR >= 1
# Rails 8.1+
# Rails 8.1 changed Scope to not support []= and Resource.new signature
# Use instance variable to track resource type
@jsonapi_resource_type = @resource_type
if block_given?
yield
else
jsonapi_relationships
end
else
# Rails 5
jsonapi_resource_scope(SingletonResource.new(@resource_type, api_only?, @scope[:shallow], options), @resource_type) do
# Rails 5-8.0
resource_arg = SingletonResource.new(@resource_type, api_only?, @scope[:shallow], options)

jsonapi_resource_scope(resource_arg, @resource_type) do
if block_given?
yield
else
Expand Down Expand Up @@ -123,17 +135,29 @@ def jsonapi_resources(*resources, &_block)

resources @resource_type, options do
# :nocov:
if @scope.respond_to? :[]=
if @scope.respond_to?(:[]=)
# Rails 4
@scope[:jsonapi_resource] = @resource_type
if block_given?
yield
else
jsonapi_relationships
end
elsif Rails::VERSION::MAJOR >= 8 && Rails::VERSION::MINOR >= 1
# Rails 8.1+
# Rails 8.1 changed Scope to not support []= and Resource.new signature
# Use instance variable to track resource type
@jsonapi_resource_type = @resource_type
if block_given?
yield
else
jsonapi_relationships
end
else
# Rails 5
jsonapi_resource_scope(Resource.new(@resource_type, api_only?, @scope[:shallow], options), @resource_type) do
# Rails 5-8.0
resource_arg = Resource.new(@resource_type, api_only?, @scope[:shallow], options)

jsonapi_resource_scope(resource_arg, @resource_type) do
if block_given?
yield
else
Expand Down Expand Up @@ -277,7 +301,7 @@ def jsonapi_resource_scope(resource, resource_type) #:nodoc:
private

def resource_type_with_module_prefix(resource = nil)
resource_name = resource || @scope[:jsonapi_resource]
resource_name = resource || @scope[:jsonapi_resource] || @jsonapi_resource_type
[@scope[:module], resource_name].compact.collect(&:to_s).join('/')
end
end
Expand Down
6 changes: 3 additions & 3 deletions test/fixtures/active_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
end

create_table :posts, force: true do |t|
t.string :title, length: 255
t.string :title, limit: 255
t.text :body
t.integer :author_id
t.integer :parent_post_id
Expand Down Expand Up @@ -324,8 +324,8 @@

create_table :related_things, force: true do |t|
t.string :name
t.references :from, references: :thing
t.references :to, references: :thing
t.references :from, foreign_key: false
t.references :to, foreign_key: false

t.timestamps null: false
end
Expand Down
14 changes: 10 additions & 4 deletions test/integration/requests/request_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,8 @@ def test_put_invalid_json

assert_equal 400, status
assert_equal 'Bad Request', json_response['errors'][0]['title']
assert_match 'unexpected token at', json_response['errors'][0]['detail']
# Rails 8.1+ has more detailed JSON error messages
assert_match(/unexpected token at|expected .* got:|parse error/i, json_response['errors'][0]['detail'])
end

def test_put_valid_json_but_array
Expand Down Expand Up @@ -1367,17 +1368,22 @@ def test_deprecated_include_parameter_not_allowed
end

def test_deprecated_include_message
ActiveSupport::Deprecation.silenced = false
# Rails 7.2+ made silenced= private
if ActiveSupport::Deprecation.respond_to?(:silenced=)
ActiveSupport::Deprecation.silenced = false
end
original_config = JSONAPI.configuration.dup
_out, err = capture_io do
eval <<-CODE
JSONAPI.configuration.allow_include = false
CODE
end
assert_match /DEPRECATION WARNING: `allow_include` has been replaced by `default_allow_include_to_one` and `default_allow_include_to_many` options./, err
assert_match /DEPRECATION|`allow_include` has been replaced/i, err
ensure
JSONAPI.configuration = original_config
ActiveSupport::Deprecation.silenced = true
if ActiveSupport::Deprecation.respond_to?(:silenced=)
ActiveSupport::Deprecation.silenced = true
end
end


Expand Down
Loading