Permalink
Browse files

Fix localized field sorting on embedded docs.

[ fix #2598 ]
  • Loading branch information...
1 parent e0f8a34 commit 31cd45f9f1666a809c5240310fab9e18e64c3b7b @durran durran committed Dec 2, 2012
View
@@ -10,6 +10,8 @@ For instructions on upgrading to newer versions, visit
* \#2600 Instantiate the proper class type for attributes when using
multi parameter attributes. (xxswingxx)
+* \#2598 Fixed sorting on localized fields with embedded docs.
+
* \#2588 Block defining methods for dynamic attributes that would be invalid
ruby methods. (Matt Sanford)
@@ -58,7 +58,12 @@ def has_attribute?(name)
#
# @since 1.0.0
def read_attribute(name)
- attributes[name.to_s]
+ normalized = name.to_s
+ if hash_dot_syntax?(normalized)
+ attributes.__nested__(normalized)
+ else
+ attributes[normalized]
+ end
end
alias :[] :read_attribute
@@ -221,6 +226,20 @@ def #{name}=(value)
WRITER
end
+ # Does the string contain dot syntax for accessing hashes?
+ #
+ # @api private
+ #
+ # @example Is the string in dot syntax.
+ # model.hash_dot_syntax?
+ #
+ # @return [ true, false ] If the string contains a "."
+ #
+ # @since 3.0.15
+ def hash_dot_syntax?(string)
+ string =~ /\./
+ end
+
# Used for allowing accessor methods for dynamic attributes.
#
# @param [ String, Symbol ] name The name of the method.
@@ -72,6 +72,25 @@ def extract_id
self["_id"] || self["id"] || self[:id] || self[:_id]
end
+ # Fetch a nested value via dot syntax.
+ #
+ # @example Fetch a nested value via dot syntax.
+ # { "name" => { "en" => "test" }}.__nested__("name.en")
+ #
+ # @param [ String ] string the dot syntax string.
+ #
+ # @return [ Object ] The matching value.
+ #
+ # @since 3.0.15
+ def __nested__(string)
+ keys = string.split(".")
+ value = self
+ keys.each do |key|
+ value = value[key]
+ end
+ value
+ end
+
# Turn the object from the ruby type we deal with to a Mongo friendly
# type.
#
@@ -17,6 +17,7 @@ class Address
field :map, type: Hash
field :move_in, type: DateTime
field :s, type: String, as: :suite
+ field :name, localize: true
embeds_many :locations, validate: false
embeds_one :code, validate: false
@@ -28,6 +28,7 @@ class Person
field :t, as: :test, type: String
field :i, as: :inte, type: Integer
field :a, as: :array, type: Array
+ field :desc, localize: true
index age: 1
index addresses: 1
@@ -24,6 +24,27 @@
Person.new
end
+ context "when accessing a localized field" do
+
+ before do
+ person.desc = "testing"
+ end
+
+ context "when passing just the name" do
+
+ it "returns the full value" do
+ person[:desc].should eq("en" => "testing")
+ end
+ end
+
+ context "when passing the name with locale" do
+
+ it "returns the value for the locale" do
+ person["desc.en"].should eq("testing")
+ end
+ end
+ end
+
context "when attribute does not exist" do
it "returns the default value" do
@@ -786,15 +786,15 @@
describe "#sort" do
let(:hobrecht) do
- Address.new(street: "hobrecht", number: 9)
+ Address.new(street: "hobrecht", number: 9, name: "hobrecht")
end
let(:friedel) do
- Address.new(street: "friedel", number: 1)
+ Address.new(street: "friedel", number: 1, name: "friedel")
end
let(:pfluger) do
- Address.new(street: "pfluger", number: 5)
+ Address.new(street: "pfluger", number: 5, name: "pfluger")
end
let(:criteria) do
@@ -911,8 +911,15 @@
end
end
- pending "with localized field" do
+ context "with localized field" do
+ let!(:sorted) do
+ context.sort("name.en" => 1)
+ end
+
+ it "sorts the documents" do
+ context.entries.should eq([ friedel, hobrecht, pfluger ])
+ end
end
end
@@ -99,6 +99,36 @@
end
end
+ describe "#asc" do
+
+ let(:person) do
+ Person.create
+ end
+
+ context "when the documents are embedded" do
+
+ let!(:hobrecht) do
+ person.addresses.create(street: "hobrecht", name: "hobrecht")
+ end
+
+ let!(:friedel) do
+ person.addresses.create(street: "friedel", name: "friedel")
+ end
+
+ let!(:pfluger) do
+ person.addresses.create(street: "pfluger", name: "pfluger")
+ end
+
+ let(:criteria) do
+ person.addresses.asc(:name)
+ end
+
+ it "returns the sorted documents" do
+ criteria.should eq([ friedel, hobrecht, pfluger ])
+ end
+ end
+ end
+
describe "#aggregates" do
context "when provided a single field" do
@@ -864,7 +864,7 @@
describe "#becomes" do
before(:all) do
- Person.validates_format_of :ssn, without: /\$\$\$/
+ Person.validates_format_of(:ssn, without: /\$\$\$/)
class Manager < Person
field :level, type: Integer, default: 1

0 comments on commit 31cd45f

Please sign in to comment.