Skip to content

Commit

Permalink
Avoid unnecessary solr query
Browse files Browse the repository at this point in the history
If only one property has been defined for a predicate,
there's no reason to run a query to filter the results by class.
This avoids a call to solr that is unnecessary in most situations.
  • Loading branch information
jcoyne committed Jun 29, 2015
1 parent d6784e2 commit 0568214
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 4 deletions.
12 changes: 8 additions & 4 deletions lib/active_fedora/associations/rdf.rb
Expand Up @@ -33,9 +33,15 @@ def filtered_results
end
end

# TODO Detect when this is the only relationship for this predicate, then skip the filtering.
def filtering_required?
reflection.klass != ActiveFedora::Base
return false if reflection.klass == ActiveFedora::Base
reflections_with_same_predicate.count > 1
end

# Count the number of reflections that have the same predicate as the reflection
# for this association.
def reflections_with_same_predicate
owner.class.outgoing_reflections.select { |k, v| v.options[:predicate] == reflection.predicate }
end

# @return [Array<RDF::URI>]
Expand All @@ -48,8 +54,6 @@ def rdf_query
owner.resource.query(subject: owner.rdf_subject, predicate: reflection.predicate).enum_statement
end


# TODO this is a huge waste of time that can be completely avoided if the attributes aren't sharing predicates.
# @return [Array<RDF::URI>]
def filter_by_class(candidate_uris)
return [] if candidate_uris.empty?
Expand Down
49 changes: 49 additions & 0 deletions spec/integration/associations/rdf_spec.rb
@@ -0,0 +1,49 @@
require 'spec_helper'

describe "rdf associations" do
context "when there is one relationship for the predicate" do
before do
class Foo < ActiveFedora::Base
end
class Library < ActiveFedora::Base
has_and_belongs_to_many :foos, predicate: ::RDF::URI('http://example.com')
end
end
after do
Object.send(:remove_const, :Foo)
Object.send(:remove_const, :Library)
end

let(:library) { Library.new }

it "doesn't not bother to filter by class type" do
expect(library.association(:foo_ids)).not_to receive(:filter_by_class)
library.foos.to_a
end
end

context "when two relationships have the same predicate" do
before do
class Foo < ActiveFedora::Base
end
class Bar < ActiveFedora::Base
end
class Library < ActiveFedora::Base
has_and_belongs_to_many :foos, predicate: ::RDF::URI('http://example.com')
has_and_belongs_to_many :bars, predicate: ::RDF::URI('http://example.com')
end
end
after do
Object.send(:remove_const, :Foo)
Object.send(:remove_const, :Bar)
Object.send(:remove_const, :Library)
end

let(:library) { Library.new }

it "filters by class type" do
expect(library.association(:foo_ids)).to receive(:filter_by_class).and_call_original
library.foos.to_a
end
end
end

0 comments on commit 0568214

Please sign in to comment.