Skip to content

Commit 7aa3cff

Browse files
p-mongop
andauthored
Fix MONGOID-5327 Prohibit using undefined string/symbol types when declaring fields (#5257)
Co-authored-by: Oleg Pudeyev <[email protected]>
1 parent 64ecc10 commit 7aa3cff

File tree

6 files changed

+108
-0
lines changed

6 files changed

+108
-0
lines changed

lib/config/locales/en.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,13 @@ en:
181181
\_\_end\n\n
182182
Refer to:
183183
https://docs.mongodb.com/mongoid/current/reference/fields/#custom-field-options"
184+
invalid_field_type:
185+
message: "Invalid field type %{type_inspection} for field '%{field}' on model '%{klass}'."
186+
summary: "Model '%{klass}' defines a field '%{field}' with an unknown type value
187+
%{type_inspection}."
188+
resolution: "Please provide a valid type value for the field.
189+
Refer to:
190+
https://docs.mongodb.com/mongoid/current/reference/fields/#using-symbols-or-strings-instead-of-classes"
184191
invalid_includes:
185192
message: "Invalid includes directive: %{klass}.includes(%{args})"
186193
summary: "Eager loading in Mongoid only supports providing arguments

lib/mongoid/errors.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
require "mongoid/errors/invalid_dependent_strategy"
1616
require "mongoid/errors/invalid_field"
1717
require "mongoid/errors/invalid_field_option"
18+
require "mongoid/errors/invalid_field_type"
1819
require "mongoid/errors/invalid_find"
1920
require "mongoid/errors/invalid_includes"
2021
require "mongoid/errors/invalid_index"
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# frozen_string_literal: true
2+
3+
module Mongoid
4+
module Errors
5+
6+
# This error is raised when trying to define a field using a :type option value
7+
# that is not present in the field type mapping.
8+
class InvalidFieldType < MongoidError
9+
10+
# Create the new error.
11+
#
12+
# @example Instantiate the error.
13+
# InvalidFieldType.new('Person', 'first_name', 'stringgy')
14+
#
15+
# @param [ String ] klass The model class.
16+
# @param [ String ] field The field on which the invalid type is used.
17+
# @param [ Symbol | String ] type The value of the field :type option.
18+
def initialize(klass, field, type)
19+
super(
20+
compose_message('invalid_field_type',
21+
klass: klass, field: field, type_inspection: type.inspect)
22+
)
23+
end
24+
end
25+
end
26+
end

lib/mongoid/fields.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,9 @@ def field_for(name, options)
733733
opts = options.merge(klass: self)
734734
type_mapping = TYPE_MAPPINGS[options[:type]]
735735
opts[:type] = type_mapping || unmapped_type(options)
736+
unless opts[:type].is_a?(Class)
737+
raise Errors::InvalidFieldType.new(self, name, options[:type])
738+
end
736739
return Fields::Localized.new(name, opts) if options[:localize]
737740
return Fields::ForeignKey.new(name, opts) if options[:identity]
738741
Fields::Standard.new(name, opts)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# frozen_string_literal: true
2+
3+
require "spec_helper"
4+
5+
describe Mongoid::Errors::InvalidFieldType do
6+
7+
describe "#message" do
8+
9+
let(:error) do
10+
described_class.new(Person, :first_name, :stringgy)
11+
end
12+
13+
context 'when type is a symbol' do
14+
let(:error) do
15+
described_class.new(Person, :first_name, :stringgy)
16+
end
17+
18+
it "contains the problem in the message" do
19+
expect(error.message).to include(
20+
"Invalid field type :stringgy for field 'first_name' on model 'Person'."
21+
)
22+
end
23+
24+
it "contains the summary in the message" do
25+
expect(error.message).to include(
26+
"Model 'Person' defines a field 'first_name' with an unknown type value :stringgy."
27+
)
28+
end
29+
end
30+
31+
context 'when type is a string' do
32+
let(:error) do
33+
described_class.new(Person, :first_name, 'stringgy')
34+
end
35+
36+
it "contains the problem in the message" do
37+
expect(error.message).to include(
38+
%q,Invalid field type "stringgy" for field 'first_name' on model 'Person'.,
39+
)
40+
end
41+
42+
it "contains the summary in the message" do
43+
expect(error.message).to include(
44+
%q,Model 'Person' defines a field 'first_name' with an unknown type value "stringgy".,
45+
)
46+
end
47+
end
48+
49+
it "contains the resolution in the message" do
50+
expect(error.message).to include(
51+
'Please provide a valid type value for the field.'
52+
)
53+
end
54+
end
55+
end

spec/mongoid/fields_spec.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,22 @@
393393
it "converts :time to Time" do
394394
expect(klass.field(:test, type: :time).type).to be(Time)
395395
end
396+
397+
context 'when using an unknown symbol' do
398+
it 'raises InvalidFieldType' do
399+
lambda do
400+
klass.field(:test, type: :bogus)
401+
end.should raise_error(Mongoid::Errors::InvalidFieldType, /defines a field 'test' with an unknown type value :bogus/)
402+
end
403+
end
404+
405+
context 'when using an unknown string' do
406+
it 'raises InvalidFieldType' do
407+
lambda do
408+
klass.field(:test, type: 'bogus')
409+
end.should raise_error(Mongoid::Errors::InvalidFieldType, /defines a field 'test' with an unknown type value "bogus"/)
410+
end
411+
end
396412
end
397413

398414
context "when the options are valid" do

0 commit comments

Comments
 (0)