Skip to content

Commit eff554b

Browse files
MONGOID-5816: attr_readonly leaks into sibling classes (#5918)
1 parent c6f9073 commit eff554b

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

lib/mongoid/attributes/readonly.rb

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ module Readonly
2323
# @return [ true | false ] If the document is new, or if the field is not
2424
# readonly.
2525
def attribute_writable?(name)
26-
new_record? || (!readonly_attributes.include?(name) && _loaded?(name))
26+
new_record? || (!self.class.readonly_attributes.include?(name) && _loaded?(name))
2727
end
2828

2929
private
@@ -63,12 +63,17 @@ module ClassMethods
6363
# end
6464
#
6565
# @param [ Symbol... ] *names The names of the fields.
66+
# @note When a parent class contains readonly attributes and is then
67+
# inherited by a child class, the child class will inherit the
68+
# parent's readonly attributes at the time of its creation.
69+
# Updating the parent does not propagate down to child classes after wards.
6670
def attr_readonly(*names)
71+
self.readonly_attributes = self.readonly_attributes.dup
6772
names.each do |name|
68-
readonly_attributes << database_field_name(name)
73+
self.readonly_attributes << database_field_name(name)
6974
end
7075
end
7176
end
7277
end
7378
end
74-
end
79+
end

spec/mongoid/attributes/readonly_spec.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,26 @@
266266
expect(child.mother).to be_nil
267267
end
268268
end
269+
end
270+
271+
context "when a subclass inherits readonly fields" do
272+
let(:attributes) do
273+
[:title, :terms]
274+
end
275+
276+
before do
277+
class OldPerson < Person
278+
attr_readonly :age
279+
end
280+
end
269281

282+
it "ensures subclass inherits the readonly attributes from parent" do
283+
expect(OldPerson.readonly_attributes.to_a).to include("title","terms")
284+
end
285+
286+
it "ensures subclass does not modify parent's readonly attributes" do
287+
expect(Person.readonly_attributes.to_a).not_to include("age")
288+
end
270289
end
271290
end
272291
end

0 commit comments

Comments
 (0)