Repository navigation
fix ArgumentError building routes on Rails 8.1 - #1496
Conversation
Signed-off-by: Sai Asish Y <say.apm35@gmail.com>
|
LGTM, but can you look at the failing test? |
|
I checked the failed Ruby 2.7 / Rails 6.0.6 / PostgreSQL job. It ran 675 tests with 8,767 assertions and one failure: Both that test and its helper are byte-identical between the PR head I have not reproduced the failure with the matching Ruby/Rails/PostgreSQL setup, so the cause remains unverified. The next diagnostic is a base-versus-head run with seed |
|
3 paragraphs to say "can't reproduce". Re-running. Seems flakey. |
|
Ok, I'm going to make an executive decision and merge this one because (1) the failing test is flakey, (2) I don't want to block a legit update, and (3) #1499 should fix them. |
|
Thanks for this, @kurko! In case it will help anyone else here's a monkey patch based on this PR that seems to be working in my project on
# frozen_string_literal: true
# Monkey patch to fix this issues: https://github.com/JSONAPI-Resources/jsonapi-resources/issues/1488
# Based on this PR: https://github.com/JSONAPI-Resources/jsonapi-resources/pull/1496
module ActionDispatch
module Routing
class Mapper
Resources.class_eval do
def jsonapi_resource(*resources, &_block)
@resource_type = resources.first
res = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix(@resource_type))
res._routed = true
unless res.singleton?
warn "Singleton routes created for non singleton resource #{res}. Links may not be generated correctly."
end
options = resources.extract_options!.dup
options[:controller] ||= @resource_type
options.merge!(res.routing_resource_options)
options[:path] = format_route(@resource_type)
if options[:except]
options[:except] << :new unless options[:except].include?(:new) || options[:except].include?('new')
options[:except] << :edit unless options[:except].include?(:edit) || options[:except].include?('edit')
else
options[:except] = [:new, :edit]
end
if res._immutable
options[:except] << :create unless options[:except].include?(:create) || options[:except].include?('create')
options[:except] << :update unless options[:except].include?(:update) || options[:except].include?('update')
options[:except] << :destroy unless options[:except].include?(:destroy) || options[:except].include?('destroy')
end
resource @resource_type, options do
# :nocov:
if @scope.respond_to? :[]=
# Rails 4
@scope[:jsonapi_resource] = @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
if block_given?
yield
else
jsonapi_relationships
end
end
end
# :nocov:
end
end
def jsonapi_resources(*resources, &_block)
@resource_type = resources.first
res = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix(@resource_type))
res._routed = true
if res.singleton?
warn "Singleton resource #{res} should use `jsonapi_resource` instead."
end
options = resources.extract_options!.dup
options[:controller] ||= @resource_type
options.merge!(res.routing_resource_options)
options[:param] = :id
options[:path] = format_route(@resource_type)
if res.resource_key_type == :uuid
options[:constraints] ||= {}
options[:constraints][:id] ||= /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/
end
if options[:except]
options[:except] = Array(options[:except])
options[:except] << :new unless options[:except].include?(:new) || options[:except].include?('new')
options[:except] << :edit unless options[:except].include?(:edit) || options[:except].include?('edit')
else
options[:except] = [:new, :edit]
end
if res._immutable
options[:except] << :create unless options[:except].include?(:create) || options[:except].include?('create')
options[:except] << :update unless options[:except].include?(:update) || options[:except].include?('update')
options[:except] << :destroy unless options[:except].include?(:destroy) || options[:except].include?('destroy')
end
resources @resource_type, options do
# :nocov:
if @scope.respond_to? :[]=
# Rails 4
@scope[:jsonapi_resource] = @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
if block_given?
yield
else
jsonapi_relationships
end
end
end
# :nocov:
end
end
end
end
end
end |
All Submissions:
Bug fixes and Changes to Core Features:
Test Plan:
rake testneeds a database and currently errors out on a booted-app requirement inrails/test_helpthat's unrelated to this change (reproduces the same way on master with Rails 7.2 and 8.1, so it looks like a separate pre-existing gap in test_helper.rb's Rails 8 support). To verify this fix directly I installed actionpack 7.2.2.2 and 8.1.3.1 side by side and drew routes withjsonapi_resourcesthrough a realActionDispatch::Routing::RouteSet#draw, which is whattest/unit/routing_ext_test.rbdoes. That test errors with the exactArgumentError: wrong number of arguments (given 4, expected 3)from the issue when run against master, and passes on both Rails versions with this change.Reviewer Checklist:
Fixes #1488
Rails 8.1 changed
ActionDispatch::Routing::Mapper::Resource#initialize(andSingletonResource) to takeonly:/except:as keywords instead of a trailing positional options hash (rails/rails#53689).jsonapi_resource(s)still calls both with a plain positional hash, so drawing any route on Rails 8.1 raisesArgumentError: wrong number of arguments (given 4, expected 3)before the app boots. Passingoptionswith**instead of positionally works on both the old and the new signature.