Skip to content

Clean up deprecated code and simplify validations #2573

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#### Features

* [#2572](https://github.com/ruby-grape/grape/pull/2572): Drop support ruby 2.7 and active_support 6.1 - [@ericproulx](https://github.com/ericproulx).
* [#2573](https://github.com/ruby-grape/grape/pull/2573): Clean up deprecated code - [@ericproulx](https://github.com/ericproulx).
* Your contribution here.

#### Fixes
Expand Down Expand Up @@ -1176,3 +1177,4 @@
### 0.1.0 (2010/11/13)

* Initial public release - [@mbleigh](https://github.com/mbleigh).

10 changes: 10 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
Upgrading Grape
===============

### Upgrading to >= 3.0.0

#### Old Deprecations Clean Up

- `rack_response` has been removed in favor of using `error!`.
- `Grape::Exceptions::MissingGroupType` and `Grape::Exceptions::UnsupportedGroupType` aliases `MissingGroupTypeError and `UnsupportedGroupType` have been removed.
- `Grape::Validations::Base` has been removed in favor of `Grape::Validations::Validators::Base`.

See [2573](https://github.com/ruby-grape/grape/pull/2573) for more information.

### Upgrading to >= 2.4.0

#### Grape::Middleware::Auth::Base
Expand Down
18 changes: 0 additions & 18 deletions lib/grape/dsl/inside_route.rb
Original file line number Diff line number Diff line change
Expand Up @@ -178,24 +178,6 @@ def error!(message, status = nil, additional_headers = nil, backtrace = nil, ori
original_exception: original_exception
end

# Creates a Rack response based on the provided message, status, and headers.
# The content type in the headers is set to the default content type unless provided.
# The message is HTML-escaped if the content type is 'text/html'.
#
# @param message [String] The content of the response.
# @param status [Integer] The HTTP status code.
# @params headers [Hash] (optional) Headers for the response
# (default: {Rack::CONTENT_TYPE => content_type}).
#
# Returns:
# A Rack::Response object containing the specified message, status, and headers.
#
def rack_response(message, status = 200, headers = { Rack::CONTENT_TYPE => content_type })
Grape.deprecator.warn('The rack_response method has been deprecated, use error! instead.')
message = Rack::Utils.escape_html(message) if headers[Rack::CONTENT_TYPE] == 'text/html'
Rack::Response.new(Array.wrap(message), Rack::Utils.status_code(status), headers)
end

# Redirect to a new url.
#
# @param url [String] The url to be redirect.
Expand Down
2 changes: 0 additions & 2 deletions lib/grape/exceptions/missing_group_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,3 @@ def initialize
end
end
end

Grape::Exceptions::MissingGroupTypeError = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Grape::Exceptions::MissingGroupTypeError', 'Grape::Exceptions::MissingGroupType', Grape.deprecator)
2 changes: 0 additions & 2 deletions lib/grape/exceptions/unsupported_group_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,3 @@ def initialize
end
end
end

Grape::Exceptions::UnsupportedGroupTypeError = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Grape::Exceptions::UnsupportedGroupTypeError', 'Grape::Exceptions::UnsupportedGroupType', Grape.deprecator)
27 changes: 8 additions & 19 deletions lib/grape/validations/params_scope.rb
Original file line number Diff line number Diff line change
Expand Up @@ -331,30 +331,23 @@ def validates(attrs, validations)
doc.type = coerce_type

default = validations[:default]

if (values_hash = validations[:values]).is_a? Hash
values = values_hash[:value]
# NB: excepts is deprecated
excepts = values_hash[:except]
else
values = validations[:values]
end
values = validations[:values].is_a?(Hash) ? validations.dig(:values, :value) : validations[:values]

doc.values = values

except_values = options_key?(:except_values, :value, validations) ? validations[:except_values][:value] : validations[:except_values]
except_values = validations[:except_values].is_a?(Hash) ? validations.dig(:except_values, :value) : validations[:except_values]

# NB. values and excepts should be nil, Proc, Array, or Range.
# Specifically, values should NOT be a Hash

# use values or excepts to guess coerce type when stated type is Array
coerce_type = guess_coerce_type(coerce_type, values, except_values, excepts)
coerce_type = guess_coerce_type(coerce_type, values, except_values)

# default value should be present in values array, if both exist and are not procs
check_incompatible_option_values(default, values, except_values, excepts)
check_incompatible_option_values(default, values, except_values)

# type should be compatible with values array, if both exist
validate_value_coercion(coerce_type, values, except_values, excepts)
validate_value_coercion(coerce_type, values, except_values)

doc.document attrs

Expand Down Expand Up @@ -462,18 +455,14 @@ def guess_coerce_type(coerce_type, *values_list)
coerce_type
end

def check_incompatible_option_values(default, values, except_values, excepts)
def check_incompatible_option_values(default, values, except_values)
return unless default && !default.is_a?(Proc)

raise Grape::Exceptions::IncompatibleOptionValues.new(:default, default, :values, values) if values && !values.is_a?(Proc) && !Array(default).all? { |def_val| values.include?(def_val) }

if except_values && !except_values.is_a?(Proc) && Array(default).any? { |def_val| except_values.include?(def_val) }
raise Grape::Exceptions::IncompatibleOptionValues.new(:default, default, :except, except_values)
end
return unless except_values && !except_values.is_a?(Proc) && Array(default).any? { |def_val| except_values.include?(def_val) }

return unless excepts && !excepts.is_a?(Proc)
raise Grape::Exceptions::IncompatibleOptionValues.new(:default, default, :except, excepts) \
unless Array(default).none? { |def_val| excepts.include?(def_val) }
raise Grape::Exceptions::IncompatibleOptionValues.new(:default, default, :except, except_values)
end

def validate(type, options, attrs, doc, opts)
Expand Down
7 changes: 0 additions & 7 deletions lib/grape/validations/validators/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,3 @@ def fail_fast?
end
end
end

Grape::Validations::Base = Class.new(Grape::Validations::Validators::Base) do
def self.inherited(*)
Grape.deprecator.warn 'Grape::Validations::Base is deprecated! Use Grape::Validations::Validators::Base instead.'
super
end
end
10 changes: 0 additions & 10 deletions spec/grape/api/custom_validations_spec.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
# frozen_string_literal: true

require 'shared/deprecated_class_examples'

describe Grape::Validations do
describe 'Grape::Validations::Base' do
let(:deprecated_class) do
Class.new(Grape::Validations::Base)
end

it_behaves_like 'deprecated class'
end

describe 'using a custom length validator' do
subject do
Class.new(Grape::API) do
Expand Down
20 changes: 0 additions & 20 deletions spec/grape/api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4679,26 +4679,6 @@ def uniqe_id_route
end
end

context 'rack_response deprecated' do
let(:app) do
Class.new(described_class) do
rescue_from :all do
rack_response('deprecated', 500, 'Content-Type' => 'text/plain')
end

get 'test' do
raise ArgumentError
end
end
end

it 'raises a deprecation' do
expect(Grape.deprecator).to receive(:warn).with('The rack_response method has been deprecated, use error! instead.')
get 'test'
expect(last_response.body).to eq('deprecated')
end
end

context 'rescue_from context' do
subject { last_response }

Expand Down
8 changes: 0 additions & 8 deletions spec/grape/exceptions/missing_group_type_spec.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
# frozen_string_literal: true

require 'shared/deprecated_class_examples'

RSpec.describe Grape::Exceptions::MissingGroupType do
describe '#message' do
subject { described_class.new.message }

it { is_expected.to include 'group type is required' }
end

describe 'Grape::Exceptions::MissingGroupTypeError' do
let(:deprecated_class) { Grape::Exceptions::MissingGroupTypeError }

it_behaves_like 'deprecated class'
end
end
8 changes: 0 additions & 8 deletions spec/grape/exceptions/unsupported_group_type_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# frozen_string_literal: true

require 'shared/deprecated_class_examples'

RSpec.describe Grape::Exceptions::UnsupportedGroupType do
subject { described_class.new }

Expand All @@ -10,10 +8,4 @@

it { is_expected.to include 'group type must be Array, Hash, JSON or Array[JSON]' }
end

describe 'Grape::Exceptions::UnsupportedGroupTypeError' do
let(:deprecated_class) { Grape::Exceptions::UnsupportedGroupTypeError }

it_behaves_like 'deprecated class'
end
end
Loading