Skip to content
Closed
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f0342fd
Add log/*.log to .gitignore and remove development.log
koji-takao-sp Nov 1, 2025
77c9da2
Add comprehensive coverage measurement with SimpleCov
koji-takao-sp Oct 31, 2025
29e4e4f
Add Rails 7.1 compatibility (partial - 664/674 tests passing)
koji-takao-sp Oct 31, 2025
e2f6441
Complete Rails 7.1.6 support with Rack 3.0 compatibility
koji-takao-sp Oct 31, 2025
cda51a6
Complete Rails 7.2.3 support
koji-takao-sp Nov 1, 2025
de5dfea
Complete Rails 8.0.4 support
koji-takao-sp Nov 1, 2025
d277fc4
Add partial Rails 8.1.2 support (664/674 tests passing)
koji-takao-sp Nov 1, 2025
85d6cce
Add complete Rails 8.1.2 support
koji-takao-sp Nov 1, 2025
88e01a4
Fix Rails 5.2-6.1 compatibility in test_helper.rb
koji-takao-sp Jan 20, 2026
93cf21f
Sync test_helper.rb compatibility fixes from docker-support
koji-takao-sp Jan 20, 2026
878520c
Add Logger require for Ruby 2.6 compatibility
koji-takao-sp Jan 20, 2026
01bdcd4
Fix unstable ordering in BookCommentResource for PostgreSQL
koji-takao-sp Jan 20, 2026
0914344
Fix test_warn_on_joined_to_many for Ruby 2.7 with Rails 5.2
koji-takao-sp Jan 20, 2026
2c4e452
Fix unstable ordering in Book associations for PostgreSQL
koji-takao-sp Jan 20, 2026
013f87a
Update CI matrix for Ruby 3.3, 3.4 and Rails 6.1-8.1
koji-takao-sp Jan 20, 2026
ae2e6af
Add csv gem dependency for Ruby 3.4+ support
koji-takao-sp Jan 20, 2026
dbb5e1a
Add default_scope to BookComment for stable ordering
koji-takao-sp Jan 20, 2026
7a7b80e
Merge pull request #9 from speee/rails-8.1-support-core
koji-takao-sp Jan 20, 2026
3fbf28b
Add Docker support for multi-version Rails testing
koji-takao-sp Jan 20, 2026
9783d74
Add Docker services for Rails 7.1-8.1 testing
koji-takao-sp Jan 20, 2026
d51c6dd
Fix Docker command to remove Gemfile.lock before bundle install
koji-takao-sp Jan 20, 2026
d4203e2
Add SQLite WAL mode files to .gitignore
koji-takao-sp Jan 20, 2026
5ff7f95
Add Docker services for Rails 5.1, 5.2, and 6.0
koji-takao-sp Jan 20, 2026
74294a5
Add Ruby 2.7 Dockerfile for Rails 5.1-6.0 compatibility
koji-takao-sp Jan 20, 2026
44f9266
Fix bundler version for Ruby 2.7 compatibility
koji-takao-sp Jan 20, 2026
5c90b83
Fix Psych::DisallowedClass error for Rails 6.0 with Ruby 2.7+
koji-takao-sp Jan 20, 2026
d78b012
Change Rails 6.1-8.1 to use Ruby 3.1.5
koji-takao-sp Jan 20, 2026
49d75c6
Use Ruby 3.1.5 for Rails 6.1-7.2, Ruby 3.4 for Rails 8.0-8.1
koji-takao-sp Jan 20, 2026
37bad60
Merge pull request #10 from speee/docker-support-speee
koji-takao-sp Jan 20, 2026
005a426
Fix Rails 8.2 deprecation warnings and improve Rack compatibility
koji-takao-sp Jan 20, 2026
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
64 changes: 61 additions & 3 deletions .github/workflows/ruby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,36 +31,94 @@ jobs:
- '3.0'
- 3.1
- 3.2
- 3.3
- 3.4
rails:
- 7.0.4
- 6.1.7
- 8.1.2
- 8.0.4
- 7.2.3
- 7.1.6
- 7.0.10
- 6.1.7.10
- 6.0.6
- 5.2.8.1
- 5.1.7
database_url:
- postgresql://postgres:password@localhost:5432/test
- sqlite3:test_db
exclude:
# Ruby 3.4 exclusions (Rails 7.2+)
- ruby: 3.4
rails: 7.1.6
- ruby: 3.4
rails: 7.0.10
- ruby: 3.4
rails: 6.1.7.10
- ruby: 3.4
rails: 6.0.6
- ruby: 3.4
rails: 5.2.8.1
- ruby: 3.4
rails: 5.1.7
# Ruby 3.3 exclusions (Rails 6.1+)
- ruby: 3.3
rails: 6.0.6
- ruby: 3.3
rails: 5.2.8.1
- ruby: 3.3
rails: 5.1.7
# Ruby 3.2 exclusions (Rails 7.0+)
- ruby: 3.2
rails: 6.0.6
- ruby: 3.2
rails: 5.2.8.1
- ruby: 3.2
rails: 5.1.7
# Ruby 3.1 exclusions (Rails 6.1+)
- ruby: 3.1
rails: 8.1.2
- ruby: 3.1
rails: 8.0.4
- ruby: 3.1
rails: 6.0.6
- ruby: 3.1
rails: 5.2.8.1
- ruby: 3.1
rails: 5.1.7
# Ruby 3.0 exclusions (Rails 6.1+)
- ruby: '3.0'
rails: 8.1.2
- ruby: '3.0'
rails: 8.0.4
- ruby: '3.0'
rails: 7.2.3
- ruby: '3.0'
rails: 6.0.6
- ruby: '3.0'
rails: 5.2.8.1
- ruby: '3.0'
rails: 5.1.7
# Ruby 2.7 exclusions (Rails 5.1-7.0)
- ruby: 2.7
rails: 8.1.2
- ruby: 2.7
rails: 8.0.4
- ruby: 2.7
rails: 7.2.3
- ruby: 2.7
rails: 7.1.6
# Ruby 2.6 exclusions (Rails 5.1-6.1)
- ruby: 2.6
rails: 8.1.2
- ruby: 2.6
rails: 8.0.4
- ruby: 2.6
rails: 7.2.3
- ruby: 2.6
rails: 7.1.6
- ruby: 2.6
rails: 7.0.4
rails: 7.0.10
# PostgreSQL not supported on Rails 5.1.7
- database_url: postgresql://postgres:password@localhost:5432/test
rails: 5.1.7
env:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ test/version_tmp
tmp
coverage
test/log
log/*.log
test_db
test_db-journal
.idea
Expand Down
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
1 change: 1 addition & 0 deletions jsonapi-resources.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ Gem::Specification.new do |spec|
spec.add_dependency 'activerecord', '>= 5.1'
spec.add_dependency 'railties', '>= 5.1'
spec.add_dependency 'concurrent-ruby'
spec.add_dependency 'csv' # Required for Ruby 3.4+ (no longer a default gem)
end
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: 4 additions & 2 deletions test/controllers/controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3682,14 +3682,16 @@ def test_warn_on_joined_to_many
get :index, params: {fields: {posts: 'id,title'}}
assert_response :success
end
assert_equal(err, "Performance issue detected: `Api::V4::PostResource.records` returned non-normalized results in `Api::V4::PostResource.find_fragments`.\n")
assert_match(/Performance issue detected: `Api::V4::PostResource.records` returned non-normalized results in `Api::V4::PostResource.find_fragments`\./, err)

JSONAPI.configuration.warn_on_performance_issues = false
_out, err = capture_subprocess_io do
get :index, params: {fields: {posts: 'id,title'}}
assert_response :success
end
assert_empty err
# On older Ruby/Rails combinations, there may be deprecation warnings
# but we should not see the performance issue warning
refute_match(/Performance issue detected/, err)

ensure
JSONAPI.configuration = original_config
Expand Down
Loading