Skip to content
This repository has been archived by the owner on Jun 30, 2018. It is now read-only.

Instance eval with delegation proof of concept. #904

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/tire/model/search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ def search(*args, &block)
end

options = default_options.update(options)
options[:context] = eval "self", block.binding if block_given?
sort = Array( options.delete(:order) || options.delete(:sort) )

s = Tire::Search::Search.new(options.delete(:index), options)
Expand Down
6 changes: 4 additions & 2 deletions lib/tire/search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ class SearchRequestFailed < StandardError; end

class Search

attr_reader :indices, :types, :query, :facets, :filters, :options, :explain, :script_fields
attr_reader :indices, :types, :query, :facets, :filters, :options, :explain,
:script_fields, :context

def initialize(indices=nil, options={}, &block)
if indices.is_a?(Hash)
Expand All @@ -15,6 +16,7 @@ def initialize(indices=nil, options={}, &block)
end
@types = Array(options.delete(:type)).map { |type| Utils.escape(type) }
@options = options
@context = options[:context]

@path = ['/', @indices.join(','), @types.join(','), '_search'].compact.join('/').squeeze('/')

Expand Down Expand Up @@ -53,7 +55,7 @@ def params
end

def query(&block)
@query = Query.new
@query = Query.new(context: context)
block.arity < 1 ? @query.instance_eval(&block) : block.call(@query)
self
end
Expand Down
9 changes: 7 additions & 2 deletions lib/tire/search/query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ module Tire
module Search

class Query
attr_accessor :value
attr_accessor :value, :context

def initialize(&block)
def initialize(options = {}, &block)
@value = {}
@context = options[:context]
block.arity < 1 ? self.instance_eval(&block) : block.call(self) if block_given?
end

def method_missing(method, *args, &block)
context.send method, *args, &block
end

def term(field, value, options={})
query = if value.is_a?(Hash)
{ field => value.to_hash }
Expand Down
18 changes: 18 additions & 0 deletions test/integration/active_model_searchable_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ def teardown
SupermodelArticle.all.each { |a| a.destroy }
end

def dummy_method_for_block_context
"test"
end

context "ActiveModel integration" do

setup do
Expand Down Expand Up @@ -86,6 +90,20 @@ def teardown
assert_equal 'abc123', results.first.id
end

should "return result of query when using methods defined in the scope" do
a = SupermodelArticle.new :title => 'Test'
a.save
a.index.refresh

s = SupermodelArticle.search do
query { match :title, dummy_method_for_block_context }
end

assert_equal 1, s.results.count
end



should "return facets" do
a = SupermodelArticle.new :title => 'Test'
a.save
Expand Down
75 changes: 65 additions & 10 deletions test/unit/model_search_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,15 @@ class SearchTest < Test::Unit::TestCase
Tire::Search::Search.
expects(:new).
with('active_model_articles', { :type => 'active_model_article' }).
returns(@stub).
twice
returns(@stub)

ActiveModelArticle.search 'foo'

Tire::Search::Search.
expects(:new).
with('active_model_articles', { :type => 'active_model_article', :context => self }).
returns(@stub)

ActiveModelArticle.search { query { string 'foo' } }
end

Expand All @@ -52,49 +57,99 @@ class SearchTest < Test::Unit::TestCase
second = 'another-custom-index-name'
expected_options = { :type => ActiveModelArticleWithCustomIndexName.document_type }

Tire::Search::Search.expects(:new).with(first, expected_options).returns(@stub).twice
Tire::Search::Search.
expects(:new).
with(first, expected_options).
returns(@stub)
ActiveModelArticleWithCustomIndexName.index_name first
ActiveModelArticleWithCustomIndexName.search 'foo'

Tire::Search::Search.
expects(:new).
with(first, expected_options.merge(:context => self)).
returns(@stub)

ActiveModelArticleWithCustomIndexName.search { query { string 'foo' } }

Tire::Search::Search.expects(:new).with(second, expected_options).returns(@stub).twice
Tire::Search::Search.
expects(:new).
with(second, expected_options).
returns(@stub)
ActiveModelArticleWithCustomIndexName.index_name second
ActiveModelArticleWithCustomIndexName.search 'foo'

Tire::Search::Search.
expects(:new).
with(second, expected_options.merge(:context => self)).
returns(@stub)

ActiveModelArticleWithCustomIndexName.search { query { string 'foo' } }

Tire::Search::Search.expects(:new).with(first, expected_options).returns(@stub).twice
Tire::Search::Search.
expects(:new).
with(first, expected_options).
returns(@stub)

ActiveModelArticleWithCustomIndexName.index_name first
ActiveModelArticleWithCustomIndexName.search 'foo'

Tire::Search::Search.
expects(:new).
with(first, expected_options.merge(:context => self)).
returns(@stub)

ActiveModelArticleWithCustomIndexName.search { query { string 'foo' } }
end

should "search in custom type" do
name = ActiveModelArticleWithCustomDocumentType.index_name
Tire::Search::Search.expects(:new).with(name, { :type => 'my_custom_type' }).returns(@stub).twice
Tire::Search::Search.
expects(:new).
with(name, { :type => 'my_custom_type' }).
returns(@stub)

ActiveModelArticleWithCustomDocumentType.search 'foo'

Tire::Search::Search.
expects(:new).
with(name, { :type => 'my_custom_type', :context => self }).
returns(@stub)


ActiveModelArticleWithCustomDocumentType.search { query { string 'foo' } }
end

should "allow to pass custom document type" do
Tire::Search::Search.
expects(:new).
with(ActiveModelArticle.index_name, { :type => 'custom_type' }).
returns(@stub).
twice
returns(@stub)

ActiveModelArticle.search 'foo', :type => 'custom_type'

Tire::Search::Search.
expects(:new).
with(ActiveModelArticle.index_name, { :type => 'custom_type', :context => self }).
returns(@stub)


ActiveModelArticle.search( :type => 'custom_type' ) { query { string 'foo' } }
end

should "allow to pass custom index name" do
Tire::Search::Search.
expects(:new).
with('custom_index', { :type => ActiveModelArticle.document_type }).
returns(@stub).
twice
returns(@stub)

ActiveModelArticle.search 'foo', :index => 'custom_index'

Tire::Search::Search.
expects(:new).
with('custom_index', { :type => ActiveModelArticle.document_type, :context => self }).
returns(@stub)


ActiveModelArticle.search( :index => 'custom_index' ) do
query { string 'foo' }
end
Expand Down