Skip to content

Commit

Permalink
Merge pull request mongodb#3694 from herimedia/niels-attr_readonly-wi…
Browse files Browse the repository at this point in the history
…th-aliases

Make attr_readonly compatible with field aliases
  • Loading branch information
durran committed Apr 27, 2015
2 parents a9d6244 + 2c54159 commit 213a7b3
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 20 deletions.
4 changes: 2 additions & 2 deletions lib/mongoid/attributes/readonly.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module Readonly
#
# @since 3.0.0
def attribute_writable?(name)
new_record? || !readonly_attributes.include?(name.to_s)
new_record? || !readonly_attributes.include?(database_field_name(name))
end

module ClassMethods
Expand All @@ -47,7 +47,7 @@ module ClassMethods
# @since 3.0.0
def attr_readonly(*names)
names.each do |name|
readonly_attributes << name.to_s
readonly_attributes << database_field_name(name)
end
end
end
Expand Down
98 changes: 80 additions & 18 deletions spec/mongoid/attributes/readonly_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@
end
end

context "when providing a field alias" do

before do
Person.attr_readonly :aliased_timestamp
end

it "adds the database field name to readonly attributes" do
expect(Person.readonly_attributes.to_a).to eq([ "at" ])
end
end

context "when providing multiple fields" do

before do
Expand All @@ -33,54 +44,71 @@
context "when creating a new document with a readonly field" do

before do
Person.attr_readonly :title, :terms
Person.attr_readonly :title, :terms, :aliased_timestamp
end

let(:person) do
Person.create(title: "sir", terms: true)
Person.create(title: "sir", terms: true, aliased_timestamp: Time.at(42))
end

it "sets the first readonly value" do
expect(person.title).to eq("sir")
end

it "sets subsequent readonly values" do
it "sets the second readonly value" do
expect(person.terms).to be true
end

it "sets the third readonly value" do
expect(person.aliased_timestamp).to eq(Time.at(42))
end

it "persists the first readonly value" do
expect(person.reload.title).to eq("sir")
end

it "persists subsequent readonly values" do
it "persists the second readonly value" do
expect(person.reload.terms).to be true
end

it "persists the third readonly value" do
expect(person.reload.aliased_timestamp).to eq(Time.at(42))
end
end

context "when updating an existing readonly field" do

before do
Person.attr_readonly :title, :terms, :score
Person.attr_readonly :title, :terms, :score, :aliased_timestamp
end

let(:person) do
Person.create(title: "sir", terms: true, score: 1)
Person.create(title: "sir", terms: true, score: 1, aliased_timestamp: Time.at(42))
end

context "when updating via the setter" do

before do
person.title = "mr"
person.aliased_timestamp = Time.at(43)
person.save
end

it "does not update the field" do
it "does not update the first field" do
expect(person.title).to eq("sir")
end

it "does not persist the changes" do
it "does not update the second field" do
expect(person.aliased_timestamp).to eq(Time.at(42))
end

it "does not persist the first field" do
expect(person.reload.title).to eq("sir")
end

it "does not persist the second field" do
expect(person.reload.aliased_timestamp).to eq(Time.at(42))
end
end

context "when updating via inc" do
Expand Down Expand Up @@ -127,64 +155,98 @@

before do
person[:title] = "mr"
person[:aliased_timestamp] = Time.at(43)
person.save
end

it "does not update the field" do
it "does not update the first field" do
expect(person.title).to eq("sir")
end

it "does not persist the changes" do
it "does not update the second field" do
expect(person.aliased_timestamp).to eq(Time.at(42))
end

it "does not persist the first field" do
expect(person.reload.title).to eq("sir")
end

it "does not persist the second field" do
expect(person.reload.aliased_timestamp).to eq(Time.at(42))
end
end

context "when updating via write_attribute" do

before do
person.write_attribute(:title, "mr")
person.write_attribute(:aliased_timestamp, Time.at(43))
person.save
end

it "does not update the field" do
it "does not update the first field" do
expect(person.title).to eq("sir")
end

it "does not persist the changes" do
it "does not update the second field" do
expect(person.aliased_timestamp).to eq(Time.at(42))
end

it "does not persist the first field" do
expect(person.reload.title).to eq("sir")
end

it "does not persist the second field" do
expect(person.reload.aliased_timestamp).to eq(Time.at(42))
end
end

context "when updating via update_attributes" do

before do
person.update_attributes(title: "mr")
person.update_attributes(title: "mr", aliased_timestamp: Time.at(43))
person.save
end

it "does not update the field" do
it "does not update the first field" do
expect(person.title).to eq("sir")
end

it "does not persist the changes" do
it "does not update the second field" do
expect(person.aliased_timestamp).to eq(Time.at(42))
end

it "does not persist the first field" do
expect(person.reload.title).to eq("sir")
end

it "does not persist the second field" do
expect(person.reload.aliased_timestamp).to eq(Time.at(42))
end
end

context "when updating via update_attributes!" do

before do
person.update_attributes!(title: "mr")
person.update_attributes!(title: "mr", aliased_timestamp: Time.at(43))
person.save
end

it "does not update the field" do
it "does not update the first field" do
expect(person.title).to eq("sir")
end

it "does not persist the changes" do
it "does not update the second field" do
expect(person.aliased_timestamp).to eq(Time.at(42))
end

it "does not persist the first field" do
expect(person.reload.title).to eq("sir")
end

it "does not persist the second field" do
expect(person.reload.aliased_timestamp).to eq(Time.at(42))
end
end

context "when updating via update_attribute" do
Expand Down

0 comments on commit 213a7b3

Please sign in to comment.