Skip to content

Commit

Permalink
Ensure private attributes works with child classes
Browse files Browse the repository at this point in the history
  • Loading branch information
kbrock committed Dec 8, 2020
1 parent 865d863 commit 79e3e33
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/extensions/ar_private_attribute.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ module ArPrivateAttribute
# @param [String|Symbol] attribute name of attribute to be private from the api and reporting
# this attribute is accessible to all ruby methods. But it is not advertised.
# we do this when deprecating an attribute or when introducing an internal attribute
#
# NOTE: only use in class definitions, or child classes will be broken
def private_attribute(attribute)
self.private_attribute_names += [attribute.to_s]
end
Expand Down
60 changes: 60 additions & 0 deletions spec/lib/extensions/ar_private_attribute_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# NOTE: ApplicationRecord already included ArPrivateAttribute
let(:klass) { Class.new(ApplicationRecord) { self.table_name = "vms" } }
let(:other_klass) { Class.new(ApplicationRecord) { self.table_name = "vms" } }
let(:child_klass) { Class.new(klass) }

context ".public_attribute_names" do
it "shows regular attributes" do
Expand All @@ -13,10 +14,51 @@
expect(klass.public_attribute_names).not_to include("type")
end

it "shows virtual attributes" do
klass.virtual_attribute :superb, :string
expect(klass.public_attribute_names).to include("superb")
end

it "hides private virtual attributes" do
klass.virtual_attribute :superb, :string
klass.private_attribute :superb
expect(klass.public_attribute_names).not_to include("superb")
end

it "only hides attributes for the specified class" do
klass.private_attribute :type
expect(other_klass.public_attribute_names).to include("type")
end

context "child class" do
it "shows regular attributes" do
expect(child_klass.public_attribute_names).to include("type")
end

it "hides attributes that are private in parent class" do
klass.private_attribute :type
expect(child_klass.public_attribute_names).not_to include("type")
end

it "hides virtual attributes that are private in the parent class" do
klass.virtual_attribute :superb, :string
klass.private_attribute :superb
expect(child_klass.public_attribute_names).not_to include("superb")
end

it "hides attributes that are private in class and parent class" do
klass.private_attribute :type
child_klass.private_attribute :name
expect(child_klass.public_attribute_names).not_to include("type")
expect(child_klass.public_attribute_names).not_to include("name")
end

it "hides attribute only for class and below" do
child_klass.private_attribute :name
expect(klass.public_attribute_names).to include("name")
expect(child_klass.public_attribute_names).not_to include("name")
end
end
end

context ".private_attribute_names" do
Expand All @@ -33,5 +75,23 @@
klass.private_attribute :type
expect(other_klass.private_attribute_names).not_to include("type")
end

context "child class" do
it "starts with no private attributes" do
expect(child_klass.private_attribute_names).to be_empty
end

it "hides attributes that are private in parent class" do
klass.private_attribute :type
expect(child_klass.private_attribute_names).to include("type")
end

it "hides attributes that are private in parent class" do
klass.private_attribute :type
child_klass.private_attribute :name
expect(child_klass.private_attribute_names).to include("type")
expect(child_klass.private_attribute_names).to include("name")
end
end
end
end
7 changes: 7 additions & 0 deletions spec/models/mixins/deprecation_mixin_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,11 @@
expect(Host.arel_attribute(:address).name).to eq("hostname") # typically this is a symbol. not perfect but it works
end
end

# Host.deprecate_attribute :address, :hostname
context ".public_attribute_names" do
it "hides deprecate_attribute columns" do
expect(Host.public_attribute_names).not_to include("address")
end
end
end

0 comments on commit 79e3e33

Please sign in to comment.