Skip to content

Commit

Permalink
Added ability to append navigation properties to the root path
Browse files Browse the repository at this point in the history
  • Loading branch information
visoft committed Aug 21, 2012
1 parent e76ef18 commit d2d3a84
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 4 deletions.
23 changes: 19 additions & 4 deletions lib/ruby_odata/query_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ def initialize(root, additional_params = {})
@expands = []
@filters = []
@order_bys = []
@navigation_paths = []
@skip = nil
@top = nil
@count = nil
@links_navigation_property = nil
@additional_params = additional_params
end

Expand Down Expand Up @@ -98,7 +100,7 @@ def top(num)
# product_links = svc.execute # => returns URIs for the products under the Category with an ID of 1
def links(navigation_property)
raise OData::NotSupportedError.new("You cannot call both the `links` method and the `count` method in the same query.") if @count
@navigation_property = navigation_property
@links_navigation_property = navigation_property
self
end

Expand All @@ -111,19 +113,32 @@ def links(navigation_property)
# svc.count
# product_count = svc.execute
def count
raise OData::NotSupportedError.new("You cannot call both the `links` method and the `count` method in the same query.") if @navigation_property
raise OData::NotSupportedError.new("You cannot call both the `links` method and the `count` method in the same query.") if @links_navigation_property
@count = true
self
end

# Used to navigate to a child collection, typically used to filter or perform a similar function against the children
#
# @param [String] navigation_property the NavigationProperty to drill-down into
#
# @example
# svc.Genres('Horror Movies').navigate("Titles").filter("Name eq 'Halloween'")
def navigate(navigation_property)
@navigation_paths << Helpers.uri_escape(navigation_property)
end

# Builds the query URI (path, not including root) incorporating expands, filters, etc.
# This is used internally when the execute method is called on the service
def query
q = @root.clone

# Navigation paths come first in the query
q << "/" + @navigation_paths.join("/") unless @navigation_paths.empty?

# Handle links queries, this isn't just a standard query option
if @navigation_property
q << "/$links/#{@navigation_property}"
if @links_navigation_property
q << "/$links/#{@links_navigation_property}"
end

# Handle count queries, this isn't just a standard query option
Expand Down
28 changes: 28 additions & 0 deletions spec/query_builder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,34 @@ module OData
end
end

describe "#navigate" do
it "should allow a user to drill down into a navigaion property on an initial query" do
builder = QueryBuilder.new "Genres('Horror Movies')"
builder.navigate("Titles")
builder.filter("Name eq 'Halloween'")
builder.query.should eq "Genres('Horror%20Movies')/Titles?$filter=Name+eq+%27Halloween%27"
end
it "should allow for multiple levels of drill down" do
builder = QueryBuilder.new "Genres('Horror Movies')"
builder.navigate("Titles('6aBu')")
builder.navigate("Awards")
builder.filter("Type eq 'Afi'")
builder.query.should eq "Genres('Horror%20Movies')/Titles('6aBu')/Awards?$filter=Type+eq+%27Afi%27"
end
it "should allow for a drill down plus links" do
builder = QueryBuilder.new "Genres('Horror Movies')"
builder.navigate("Titles('6aBu')")
builder.links("Awards")
builder.query.should eq "Genres('Horror%20Movies')/Titles('6aBu')/$links/Awards"
end
it "should allow for a drill down plus count" do
builder = QueryBuilder.new "Genres('Horror Movies')"
builder.navigate("Titles")
builder.count
builder.query.should eq "Genres('Horror%20Movies')/Titles/$count"
end
end

describe "#query" do
it "should encode spaces in IDs" do
builder = QueryBuilder.new "Categories('Cool Stuff')"
Expand Down

0 comments on commit d2d3a84

Please sign in to comment.