To edit pages or tickets please login with username/password: aaf/aaf

Changeset 319

Show
Ignore:
Timestamp:
02/18/08 20:36:04 (8 months ago)
Author:
jk
Message:

only some failures left

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/demo/app/controllers/admin/backend_controller.rb

    r84 r319  
    44    @query = params[:query] || '' 
    55    unless @query.blank? 
    6       @results = Content.find_by_contents @query 
     6      @results = Content.find_with_ferret @query 
    77    end 
    88  end 
  • trunk/demo/test/unit/comment_test.rb

    r307 r319  
    3131  def test_search_for_id 
    3232    # don't search the id field by default: 
    33     assert Comment.find_by_contents('3').empty? 
     33    assert Comment.find_with_ferret('3').empty? 
    3434    # explicit query for id field works: 
    35     assert_equal 3, Comment.find_by_contents('id:3').first.id 
     35    assert_equal 3, Comment.find_with_ferret('id:3').first.id 
    3636  end 
    3737 
     
    4545    # TODO: check why this fails, but querying for 'comment fixture' works. 
    4646    # maybe different analyzers at index creation and searching time ? 
    47     #comments_from_ferret = Comment.find_by_contents('"comment from fixture"') 
    48     comments_from_ferret = Comment.find_by_contents('comment fixture') 
     47    #comments_from_ferret = Comment.find_with_ferret('"comment from fixture"') 
     48    comments_from_ferret = Comment.find_with_ferret('comment fixture') 
    4949    assert_equal 2, comments_from_ferret.size 
    5050    assert comments_from_ferret.include?(comments(:first)) 
     
    5454  def test_rebuild_index 
    5555    Comment.aaf_index.ferret_index.query_delete('comment') 
    56     comments_from_ferret = Comment.find_by_contents('comment AND fixture') 
     56    comments_from_ferret = Comment.find_with_ferret('comment AND fixture') 
    5757    assert comments_from_ferret.empty? 
    5858    Comment.rebuild_index 
    59     comments_from_ferret = Comment.find_by_contents('comment AND fixture') 
     59    comments_from_ferret = Comment.find_with_ferret('comment AND fixture') 
    6060    assert_equal 2, comments_from_ferret.size 
    6161  end 
    6262 
    6363  def test_total_hits 
    64     comments_from_ferret = Comment.find_by_contents('comment AND fixture', :limit => 1) 
     64    comments_from_ferret = Comment.find_with_ferret('comment AND fixture', :limit => 1) 
    6565    assert_equal 1, comments_from_ferret.size 
    6666    assert_equal 2, comments_from_ferret.total_hits 
    6767 
    68     comments_from_ferret = Comment.find_by_contents('comment AND fixture', {}, :conditions => 'id != 1') 
     68    comments_from_ferret = Comment.find_with_ferret('comment AND fixture', {}, :conditions => 'id != 1') 
    6969    assert_equal 1, comments_from_ferret.size 
    7070    assert_equal 1, comments_from_ferret.total_hits 
     
    7272 
    7373  def test_score 
    74     comments_from_ferret = Comment.find_by_contents('comment AND fixture', :limit => 1) 
     74    comments_from_ferret = Comment.find_with_ferret('comment AND fixture', :limit => 1) 
    7575    assert comments_from_ferret.first 
    7676    assert comments_from_ferret.first.ferret_score > 0 
     
    8181      Comment.create( :author => 'multi-commenter', :content => "This is multicomment no #{i}" ) 
    8282    end 
    83     assert_equal 10, (res = Comment.find_by_contents('multicomment')).size 
     83    assert_equal 10, (res = Comment.find_with_ferret('multicomment')).size 
    8484    assert_equal 20, res.total_hits 
    85     assert_equal 15, (res = Comment.find_by_contents('multicomment', :limit => 15)).size 
     85    assert_equal 15, (res = Comment.find_with_ferret('multicomment', :limit => 15)).size 
    8686    assert_equal 20, res.total_hits 
    87     assert_equal 20, (res = Comment.find_by_contents('multicomment', :limit => :all)).size 
     87    assert_equal 20, (res = Comment.find_with_ferret('multicomment', :limit => :all)).size 
    8888    assert_equal 20, res.total_hits 
    8989  end 
     
    101101  end 
    102102 
    103   def test_find_by_contents 
     103  def test_find_with_ferret 
    104104    comment = Comment.create( :author => 'john doe', :content => 'This is a useless comment' ) 
    105105    comment2 = Comment.create( :author => 'another', :content => 'content' ) 
    106106 
    107     comments_from_ferret = Comment.find_by_contents('anoth* OR jo*') 
     107    comments_from_ferret = Comment.find_with_ferret('anoth* OR jo*') 
    108108    assert_equal 2, comments_from_ferret.size 
    109109    assert comments_from_ferret.include?(comment) 
     
    111111     
    112112    # find options 
    113     comments_from_ferret = Comment.find_by_contents('anoth* OR jo*', {}, :conditions => ["id=?",comment2.id]) 
     113    comments_from_ferret = Comment.find_with_ferret('anoth* OR jo*', {}, :conditions => ["id=?",comment2.id]) 
    114114    assert_equal 1, comments_from_ferret.size 
    115115    assert comments_from_ferret.include?(comment2) 
    116116     
    117     comments_from_ferret = Comment.find_by_contents('lorem ipsum not here') 
    118     assert comments_from_ferret.empty? 
    119  
    120     comments_from_ferret = Comment.find_by_contents('another') 
     117    comments_from_ferret = Comment.find_with_ferret('lorem ipsum not here') 
     118    assert comments_from_ferret.empty? 
     119 
     120    comments_from_ferret = Comment.find_with_ferret('another') 
    121121    assert_equal 1, comments_from_ferret.size 
    122122    assert_equal comment2.id, comments_from_ferret.first.id 
    123123     
    124     comments_from_ferret = Comment.find_by_contents('doe') 
    125     assert_equal 1, comments_from_ferret.size 
    126     assert_equal comment.id, comments_from_ferret.first.id 
    127      
    128     comments_from_ferret = Comment.find_by_contents('useless') 
     124    comments_from_ferret = Comment.find_with_ferret('doe') 
     125    assert_equal 1, comments_from_ferret.size 
     126    assert_equal comment.id, comments_from_ferret.first.id 
     127     
     128    comments_from_ferret = Comment.find_with_ferret('useless') 
    129129    assert_equal 1, comments_from_ferret.size 
    130130    assert_equal comment.id, comments_from_ferret.first.id 
    131131   
    132132    # no monkeys here 
    133     comments_from_ferret = Comment.find_by_contents('monkey') 
     133    comments_from_ferret = Comment.find_with_ferret('monkey') 
    134134    assert comments_from_ferret.empty? 
    135135     
    136136    # multiple terms are ANDed by default... 
    137     comments_from_ferret = Comment.find_by_contents('monkey comment') 
     137    comments_from_ferret = Comment.find_with_ferret('monkey comment') 
    138138    assert comments_from_ferret.empty? 
    139139    # ...unless you connect them by OR 
    140     comments_from_ferret = Comment.find_by_contents('monkey OR comment') 
     140    comments_from_ferret = Comment.find_with_ferret('monkey OR comment') 
    141141    assert_equal 3, comments_from_ferret.size 
    142142    assert comments_from_ferret.include?(comment) 
     
    146146    # multiple terms, each term has to occur in a document to be found,  
    147147    # but they may occur in different fields 
    148     comments_from_ferret = Comment.find_by_contents('useless john') 
     148    comments_from_ferret = Comment.find_with_ferret('useless john') 
    149149    assert_equal 1, comments_from_ferret.size 
    150150    assert_equal comment.id, comments_from_ferret.first.id 
     
    152152 
    153153    # search for an exact string by enclosing it in " 
    154     comments_from_ferret = Comment.find_by_contents('"useless john"') 
    155     assert comments_from_ferret.empty? 
    156     comments_from_ferret = Comment.find_by_contents('"useless comment"') 
     154    comments_from_ferret = Comment.find_with_ferret('"useless john"') 
     155    assert comments_from_ferret.empty? 
     156    comments_from_ferret = Comment.find_with_ferret('"useless comment"') 
    157157    assert_equal 1, comments_from_ferret.size 
    158158    assert_equal comment.id, comments_from_ferret.first.id 
     
    187187    comment = Comment.create( :author => 'john doe', :content => 'Move or shake' ) 
    188188    ['move shake', 'Move shake', 'move Shake', 'move or shake', 'move the shake'].each do |q| 
    189       comments_from_ferret = Comment.find_by_contents(q) 
     189      comments_from_ferret = Comment.find_with_ferret(q) 
    190190      assert_equal comment, comments_from_ferret.first, "query #{q} failed" 
    191191    end 
     
    194194 
    195195  def test_array_conditions_combining  
    196     comments_from_ferret = Comment.find_by_contents('comment AND fixture', {}, :conditions => [ 'id IN (?)', [ 2, 3 ] ])  
     196    comments_from_ferret = Comment.find_with_ferret('comment AND fixture', {}, :conditions => [ 'id IN (?)', [ 2, 3 ] ])  
    197197    assert_equal 1, comments_from_ferret.size  
    198198    assert_equal 1, comments_from_ferret.total_hits  
  • trunk/demo/test/unit/content_test.rb

    r318 r319  
    2929 
    3030  def test_limit_all 
    31     res = Content.find_by_contents '*', { :limit => :all }, :conditions => ['lower(title) like ?', 'content'], :order => 'contents.description' 
     31    res = Content.find_with_ferret '*', { :limit => :all }, :conditions => ['lower(title) like ?', 'content'], :order => 'contents.description' 
    3232  end 
    3333 
     
    4949  end 
    5050 
    51   # weiter: single index / multisearch lazy loading 
    5251  def test_lazy_loading 
    5352    results = Content.find_with_ferret 'description', :lazy => true 
     
    356355  end 
    357356   
    358   def test_total_hits_multi 
    359     q = '*:title OR *:comment' 
    360     assert_equal 3, Comment.total_hits(q) 
    361     assert_equal 2, Content.total_hits(q) 
    362     assert_equal 5, ActsAsFerret::total_hits(q, [ Comment, Content ]) 
    363   end 
    364  
    365   def test_multi_search_sorting 
    366     sorting = [ Ferret::Search::SortField.new(:id) ] 
    367     result = Content.find_with_ferret('*:title OR *:comment', :multi => [Comment], :sort => sorting) 
    368     assert_equal result.map(&:id).sort, result.map(&:id) 
    369  
    370     sorting = [ Ferret::Search::SortField.new(:title) ] 
    371     result = Content.find_with_ferret('*:title OR *:comment', :multi => [Comment], :sort => sorting) 
    372     sorting = [ Ferret::Search::SortField.new(:title, :reverse => true) ] 
    373     result2 = Content.find_with_ferret('*:title OR *:comment', :multi => [Comment], :sort => sorting) 
    374     assert result.any? 
    375     assert result.map(&:id) != result2.map(&:id) 
    376  
    377     sorting = [ Ferret::Search::SortField::SCORE ] 
    378     result = Content.find_with_ferret('*:title OR *:comment', :multi => Comment, :sort => sorting) 
    379     assert result.any? 
    380     assert_equal result.map(&:ferret_score).sort.reverse, result.map(&:ferret_score) 
    381  
    382     sorting = [ Ferret::Search::SortField::SCORE_REV ] 
    383     result2 = Content.find_with_ferret('*:title OR *:comment', :multi => Comment, :sort => sorting) 
    384     assert_equal result2.map(&:ferret_score).sort, result2.map(&:ferret_score) 
    385     assert_equal result.map(&:ferret_score), result2.map(&:ferret_score).reverse 
    386   end 
    387  
    388357  def test_sort_class 
    389358    sorting = Ferret::Search::Sort.new(Ferret::Search::SortField.new(:id, :reverse => true)) 
     
    414383  end 
    415384   
    416   # remote index rebuilds will create an index in a directory with a timestamped name. 
    417   # the local MultiIndex instance doesn't know about this (because it's running in  
    418   # another interpreter instance than the server) and therefore fails to use the  
    419   # correct index directories. 
    420   # TODO strange, still doesn't work but it should now... 
    421   unless Content.aaf_configuration[:remote] 
    422     def test_multi_index 
    423       i =  ActsAsFerret::MultiIndex.new([Content, Comment]) 
    424       hits = i.search(TermQuery.new(:title,"title")) 
    425       assert_equal 1, hits.total_hits 
    426  
    427       qp = Ferret::QueryParser.new(:default_field => "title",  
    428                                   :analyzer => Ferret::Analysis::WhiteSpaceAnalyzer.new) 
    429       hits = i.search(qp.parse("title")) 
    430       assert_equal 1, hits.total_hits 
    431        
    432       qp = Ferret::QueryParser.new(:fields => ['title', 'content', 'description'], 
    433                         :analyzer => Ferret::Analysis::WhiteSpaceAnalyzer.new) 
    434       hits = i.search(qp.parse("title")) 
    435       assert_equal 2, hits.total_hits 
    436       hits = i.search(qp.parse("title:title OR description:title")) 
    437       assert_equal 2, hits.total_hits 
    438  
    439       hits = i.search("title:title OR description:title OR title:comment OR description:comment OR content:comment") 
    440       assert_equal 5, hits.total_hits 
    441  
    442       hits = i.search("title OR comment") 
    443       assert_equal 5, hits.total_hits 
    444  
    445       hits = i.search("title OR comment", :limit => 2) 
    446       count = 0 
    447       hits.hits.each { |hit, score| count += 1 } 
    448       assert_equal 2, count 
    449  
    450       hits = i.search("title OR comment", :offset => 2) 
    451       count = 0 
    452       hits.hits.each { |hit, score| count += 1 } 
    453       assert_equal 3, count 
    454     end 
    455   end 
    456385 
    457386  def test_add_rebuilds_index 
     
    467396  end 
    468397 
    469   def test_multi_search_rebuilds_index 
    470     remove_index Content 
    471     contents_from_ferret = Content.find_with_ferret('description:title', :multi => Comment) 
    472     assert_equal 1, contents_from_ferret.size 
    473   end 
    474  
    475   # remote index rebuilds will create an index in a directory with a timestamped name... 
    476   unless Content.aaf_configuration[:remote] 
    477     def test_multi_index_rebuilds_index 
    478       remove_index Content 
    479       i =  ActsAsFerret::MultiIndex.new([Content]) 
    480       assert File.exists?("#{ActsAsFerret::index_definition(Content)[:index_dir]}/segments") 
    481       hits = i.search("description:title") 
    482       assert_equal 1, hits.total_hits, hits.inspect 
    483     end 
    484   end 
    485  
    486   def test_multi_search_find_options 
    487     contents_from_ferret = Content.find_with_ferret('title', { :multi => Comment }, :order => 'id desc') 
    488     assert_equal 2, contents_from_ferret.size 
    489     assert contents_from_ferret.first.id > contents_from_ferret.last.id 
    490     contents_from_ferret = Content.find_with_ferret('title', { :multi => Comment }, :order => 'id asc') 
    491     assert contents_from_ferret.first.id < contents_from_ferret.last.id 
    492  
    493     contents_from_ferret = Content.find_with_ferret('title', :multi => Comment, :limit => 1) 
    494     assert_equal 1, contents_from_ferret.size 
    495     contents_from_ferret = Content.find_with_ferret('title', { :multi => Comment }, :limit => 1) 
    496     assert_equal 1, contents_from_ferret.size 
    497  
    498  
    499     more_contents(true) 
    500     r = Content.find_with_ferret('title OR comment', { :multi => Comment, :limit => :all } ) 
    501     assert_equal 60, r.size 
    502     assert_equal 60, r.total_hits 
    503  
    504     id = Content.find_with_ferret('title').first.id 
    505     r = Content.find_with_ferret('title OR comment', { :multi => Comment, :limit => :all }, 
    506                                                      { :conditions => { :content => ["id != ?", id] }}) 
    507     assert_equal 59, r.size 
    508     assert_equal 59, r.total_hits 
    509  
    510     r = Content.find_with_ferret('title OR comment', { :multi => Comment, :limit => 20 }, 
    511                                                      { :conditions => { :content => ["id != ?", id] }}) 
    512     assert_equal 20, r.size 
    513     assert_equal 59, r.total_hits 
    514  
    515     r = Content.find_with_ferret('title OR comment', { :multi => Comment, :limit => 20 }, 
    516                                                      { :conditions => { :comment => 'content is null', 
    517                                                                         :content => ["id != ?", id] }}) 
    518     assert_equal 20, r.size 
    519     assert_equal 29, r.total_hits 
    520  
    521     r = Content.find_with_ferret('title OR comment', { :multi => Comment }, 
    522                                                      { :conditions => { :content => ["id != ?", id] }, :limit => 20 }) 
    523     assert_equal 20, r.size 
    524     assert_equal 59, r.total_hits 
    525   end 
    526  
    527   def test_multi_search 
    528     assert_equal 4, ContentBase.find(:all).size 
    529      
    530     Content.aaf_index.ferret_index.flush 
    531     contents_from_ferret = Content.find_with_ferret('description:title', :multi => []) 
    532     assert_equal 1, contents_from_ferret.size 
    533     contents_from_ferret = Content.find_with_ferret('title:title OR description:title', :multi => []) 
    534     assert_equal 2, contents_from_ferret.size 
    535     contents_from_ferret = Content.find_with_ferret('title:title', :multi => []) 
    536     assert_equal 1, contents_from_ferret.size 
    537     contents_from_ferret = Content.find_with_ferret('*:title', :multi => []) 
    538     assert_equal 2, contents_from_ferret.size 
    539     contents_from_ferret = Content.find_with_ferret('title', :multi => []) 
    540     assert_equal 2, contents_from_ferret.size 
    541      
    542     assert_equal contents(:first).id, contents_from_ferret.first.id 
    543     assert_equal @another_content.id, contents_from_ferret.last.id 
    544      
    545     contents_from_ferret = Content.find_with_ferret('title', :multi => []) 
    546     assert_equal 2, contents_from_ferret.size 
    547     contents_from_ferret = Content.find_with_ferret('title', :multi => [], :limit => 1) 
    548     assert_equal 1, contents_from_ferret.size 
    549     contents_from_ferret = Content.find_with_ferret('title', :multi => [], :offset => 1) 
    550     assert_equal 1, contents_from_ferret.size 
    551  
    552     contents_from_ferret = Content.find_with_ferret('title:title OR content:comment OR description:title', :multi => [Comment]) 
    553     assert_equal 5, contents_from_ferret.size 
    554     contents_from_ferret = Content.find_with_ferret('title:title OR content:comment OR description:title', :multi => [Comment], :limit => 2) 
    555     assert_equal 2, contents_from_ferret.size 
    556  
    557     contents_from_ferret = Content.find_with_ferret('*:title OR *:comment', :multi => Comment) 
    558     assert_equal 5, contents_from_ferret.size 
    559     contents_from_ferret = Content.find_with_ferret('*:title OR *:comment', :multi => [Comment]) 
    560     assert_equal 5, contents_from_ferret.size 
    561     contents_from_ferret = Content.find_with_ferret('title:(title OR comment) OR description:(title OR comment) OR content:(title OR comment)', :multi => [Comment]) 
    562     assert_equal 5, contents_from_ferret.size 
    563   end 
    564  
    565   def test_multi_search_lazy 
    566     contents_from_ferret = Content.find_with_ferret('title', :multi => Comment, :lazy => true) 
    567     assert_equal 2, contents_from_ferret.size 
    568     contents_from_ferret.each do |record| 
    569       assert ActsAsFerret::FerretResult === record, record.inspect 
    570       assert !record.description.blank? 
    571       assert_nil record.instance_variable_get(:"@ar_record") 
    572     end 
    573   end 
    574  
    575   def test_id_multi_search 
    576     assert_equal 4, ContentBase.find(:all).size 
    577      
    578     [ 'title:title OR description:title OR content:title', 'title', '*:title'].each do |query| 
    579       total_hits, contents_from_ferret = Content.id_multi_search(query) 
    580       assert_equal 2, contents_from_ferret.size, query 
    581       assert_equal 2, total_hits, query 
    582       assert_equal contents(:first).id, contents_from_ferret.first[:id].to_i 
    583       assert_equal @another_content.id, contents_from_ferret.last[:id].to_i 
    584     end 
    585  
    586     ContentBase.rebuild_index 
    587     Comment.rebuild_index 
    588     ['title OR comment', 'title:(title OR comment) OR description:(title OR comment) OR content:(title OR comment)'].each do |query| 
    589       total_hits, contents_from_ferret = Content.id_multi_search(query, [Comment]) 
    590       assert_equal 5, contents_from_ferret.size, query 
    591       assert_equal 5, total_hits 
    592     end 
    593   end 
    594  
    595   def test_id_multi_search_lazy 
    596     total_hits, contents_from_ferret = Content.id_multi_search('title', [Comment], :lazy => true) 
    597     assert_equal 2, contents_from_ferret.size 
    598     assert_equal 2, total_hits 
    599     found = 0 
    600     contents_from_ferret.each do |data| 
    601       next if data[:model] != 'Content' 
    602       found += 1 
    603       assert !data[:data][:description].blank? 
    604     end 
    605     assert_equal 2, found 
    606   end 
    607  
    608398  def test_total_hits 
    609399    assert_equal 2, Content.total_hits('title:title OR description:title') 
     
    611401  end 
    612402 
    613   def test_find_id_by_contents 
    614     total_hits, contents_from_ferret = Content.find_id_by_contents('title:title OR description:title') 
     403  def test_find_ids_with_ferret 
     404    total_hits, contents_from_ferret = Content.find_ids_with_ferret('title:title OR description:title') 
    615405    assert_equal 2, contents_from_ferret.size 
    616406    assert_equal 2, total_hits 
     
    622412      
    623413    # give description field higher boost: 
    624     total_hits, contents_from_ferret = Content.find_id_by_contents('title:title OR description:title^200') 
     414    total_hits, contents_from_ferret = Content.find_ids_with_ferret('title:title OR description:title^200') 
    625415    assert_equal 2, contents_from_ferret.size 
    626416    assert_equal 2, total_hits 
     
    732522  end 
    733523 
    734   def test_multi_pagination 
    735     more_contents(true) 
    736  
    737     r = Content.find_with_ferret 'title OR comment', :multi => Comment, :per_page => 10, :sort => 'title' 
    738     assert_equal 60, r.total_hits 
    739     assert_equal 10, r.size 
    740     assert_equal "0", r.first.description 
    741     assert_equal "9", r.last.description 
    742     assert_equal 1, r.current_page 
    743     assert_equal 6, r.page_count 
    744  
    745     r = Content.find_with_ferret 'title OR comment', :multi => Comment, :page => '2', :per_page => 10, :sort => 'title' 
    746     assert_equal 60, r.total_hits 
    747     assert_equal 10, r.size 
    748     assert_equal "10", r.first.description 
    749     assert_equal "19", r.last.description 
    750     assert_equal 2, r.current_page 
    751     assert_equal 6, r.page_count 
    752  
    753     r = Content.find_with_ferret 'title OR comment', :multi => Comment, :page => 7, :per_page => 10, :sort => 'title' 
    754     assert_equal 60, r.total_hits 
    755     assert_equal 0, r.size 
    756   end 
    757  
    758524  def test_pagination 
    759525    more_contents 
     
    845611    assert_equal 3, r.current_page 
    846612    assert_equal 3, r.page_count 
    847   end 
    848  
    849   def test_multi_pagination_with_ar_conditions 
    850     more_contents(true) 
    851     id = Content.find_with_ferret('title').first.id 
    852     r = Content.find_with_ferret 'title OR comment', { :page => 1, :per_page => 10, :multi => Comment },  
    853                                           { :conditions => { :content => ["id != ?", id] }, :order => 'id ASC' } 
    854     assert_equal 59, r.total_hits 
    855     assert_equal 10, r.size 
    856     assert_equal "Comment for content 00", r.first.content 
    857     assert_equal "Comment for content 09", r.last.content 
    858     assert_equal 1, r.current_page 
    859     assert_equal 6, r.page_count 
    860  
    861     r = Content.find_with_ferret 'title OR comment', { :page => 6, :per_page => 10, :multi => Comment }, 
    862                                           { :conditions => { :content => [ "id != ?", id ] }, :order => 'id ASC' } 
    863     assert_equal 59, r.total_hits 
    864     assert_equal 9, r.size 
    865     assert_equal "21", r.first.description 
    866     assert_equal "29", r.last.description 
    867     assert_equal 6, r.current_page 
    868     assert_equal 6, r.page_count 
    869613  end 
    870614 
  • trunk/demo/test/unit/shared_index1_test.rb

    r317 r319  
    99 
    1010  def test_lazy_loading_shared_index 
    11     results = SharedIndex1.find_by_contents 'first', :lazy => [ :name ], :models => :all 
     11    results = SharedIndex1.find_with_ferret 'first', :lazy => [ :name ], :models => :all 
    1212    assert_equal 2, results.size 
    1313    found_lazy_result = false 
     
    2424  end 
    2525 
    26   def test_find_id_by_contents 
    27     result = SharedIndex1.find_id_by_contents("first") 
     26  def test_find_ids_with_ferret 
     27    result = SharedIndex1.find_ids_with_ferret("first") 
    2828    assert_equal 2, result.size 
    2929  end 
    3030 
    31   def test_find_by_contents_one_class 
    32     result = SharedIndex1.find_by_contents("first") 
     31  def test_find_with_ferret_one_class 
     32    result = SharedIndex1.find_with_ferret("first") 
    3333    assert_equal 1, result.size, result.inspect 
    3434    assert_equal shared_index1s(:first), result.first 
    3535 
    36     result = SharedIndex1.find_by_contents("name:first", :models => [SharedIndex1]) 
     36    result = SharedIndex1.find_with_ferret("name:first", :models => [SharedIndex1]) 
    3737    assert_equal 1, result.size 
    3838    assert_equal shared_index1s(:first), result.first 
     
    4040 
    4141  def test_custom_query 
    42     result = SharedIndex1.find_by_contents("name:first class_name:SharedIndex1") 
     42    result = SharedIndex1.find_with_ferret("name:first class_name:SharedIndex1") 
    4343    assert_equal 1, result.size 
    4444    assert_equal shared_index1s(:first), result.first 
    4545  end 
    4646 
    47   def test_find_by_contents_all_classes 
    48     result = SharedIndex1.find_by_contents("first", :models => :all) 
     47  def test_find_with_ferret_all_classes 
     48    result = SharedIndex1.find_with_ferret("first", :models => :all) 
    4949    assert_equal 2, result.size 
    5050    assert result.include?(shared_index1s(:first)) 
    5151    assert result.include?(shared_index2s(:first)) 
    5252 
    53     result = SharedIndex1.find_by_contents("name:first", :models => [SharedIndex2]) 
     53    result = SharedIndex1.find_with_ferret("name:first", :models => [SharedIndex2]) 
    5454    assert_equal 2, result.size 
    5555    assert result.include?(shared_index1s(:first)) 
     
    6363 
    6464  def test_destroy 
    65     result = SharedIndex1.find_by_contents("first OR another", :models => :all) 
     65    result = SharedIndex1.find_with_ferret("first OR another", :models => :all) 
    6666    assert_equal 4, result.size 
    6767    SharedIndex1.destroy(shared_index1s(:first)) 
    68     result = SharedIndex1.find_by_contents("first OR another", :models => :all) 
     68    result = SharedIndex1.find_with_ferret("first OR another", :models => :all) 
    6969    assert_equal 3, result.size 
    7070    shared_index2s(:first).destroy 
    71     result = SharedIndex1.find_by_contents("first OR another", :models => :all) 
     71    result = SharedIndex1.find_with_ferret("first OR another", :models => :all) 
    7272    assert_equal 2, result.size 
    7373  end 
     
    7575  def test_ferret_destroy 
    7676    SharedIndex1.rebuild_index 
    77     result = SharedIndex1.find_id_by_contents("first OR another", :models => :all) 
     77    result = SharedIndex1.find_ids_with_ferret("first OR another", :models => :all) 
    7878    assert_equal 4, result.first 
    7979    shared_index1s(:first).ferret_destroy 
    80     result = SharedIndex1.find_id_by_contents("first OR another", :models => :all) 
     80    result = SharedIndex1.find_ids_with_ferret("first OR another", :models => :all) 
    8181    assert_equal 3, result.first 
    8282  end 
     
    8484  def test_ferret_destroy_ticket_88 
    8585    SharedIndex1.rebuild_index 
    86     result = SharedIndex1.find_id_by_contents("first OR another", :models => :all) 
     86    result = SharedIndex1.find_ids_with_ferret("first OR another", :models => :all) 
    8787    assert_equal 4, result.first 
    88     result = SharedIndex2.find_id_by_contents("first OR another", :models => :all) 
     88    result = SharedIndex2.find_ids_with_ferret("first OR another", :models => :all) 
    8989    assert_equal 4, result.first 
    9090    SharedIndex1.destroy(shared_index1s(:first)) 
    91     result = SharedIndex1.find_id_by_contents("first OR another", :models => :all) 
     91    result = SharedIndex1.find_ids_with_ferret("first OR another", :models => :all) 
    9292    assert_equal 3, result.first 
    93     result = SharedIndex2.find_id_by_contents("first OR another", :models => :all) 
     93    result = SharedIndex2.find_ids_with_ferret("first OR another", :models => :all) 
    9494    assert_equal 3, result.first 
    9595    shared_index2s(:first).destroy 
    96     result = SharedIndex1.find_id_by_contents("first OR another", :models => :all) 
     96    result = SharedIndex1.find_ids_with_ferret("first OR another", :models => :all) 
    9797    assert_equal 2, result.first 
    98     result = SharedIndex2.find_id_by_contents("first OR another", :models => :all) 
     98    result = SharedIndex2.find_ids_with_ferret("first OR another", :models => :all) 
    9999    assert_equal 2, result.first 
    100100  end 
    101101 
    102102  def test_update 
    103     assert SharedIndex1.find_by_contents("new").empty? 
     103    assert SharedIndex1.find_with_ferret("new").empty? 
    104104    shared_index1s(:first).name = "new name" 
    105105    shared_index1s(:first).save 
    106     assert_equal 1, SharedIndex1.find_by_contents("new").size 
    107     assert_equal 1, SharedIndex1.find_by_contents("new").size 
    108     assert_equal 1, SharedIndex1.find_by_contents("new", :models => [SharedIndex2]).size 
    109     assert_equal 0, SharedIndex2.find_by_contents("new").size 
     106    assert_equal 1, SharedIndex1.find_with_ferret("new").size 
     107    assert_equal 1, SharedIndex1.find_with_ferret("new").size 
     108    assert_equal 1, SharedIndex1.find_with_ferret("new", :models => [SharedIndex2]).size 
     109    assert_equal 0, SharedIndex2.find_with_ferret("new").size 
    110110  end 
    111111end 
  • trunk/demo/test/unit/special_content_test.rb

    r191 r319  
    1515  end 
    1616 
    17   def test_find_by_contents 
    18     contents_from_ferret = SpecialContent.find_by_contents('single table') 
     17  def test_find_with_ferret 
     18    contents_from_ferret = SpecialContent.find_with_ferret('single table') 
    1919    assert_equal 1, contents_from_ferret.size 
    2020    assert_equal ContentBase.find(3), contents_from_ferret.first 
    21     contents_from_ferret = SpecialContent.find_by_contents('title') 
     21    contents_from_ferret = SpecialContent.find_with_ferret('title') 
    2222    assert contents_from_ferret.empty? 
    2323     
  • trunk/plugin/acts_as_ferret/lib/acts_as_ferret.rb

    r318 r319  
    195195  end 
    196196 
    197   # count hits for a query across multiple models 
     197  # count hits for a query with multiple models 
    198198  def self.total_hits(query, models, options = {}) 
    199     models = [models] unless Array === models 
    200199    get_index_for(*models).total_hits query, options.merge( :models => models ) 
     200  end 
     201 
     202  # find ids of records with multiple models 
     203  def self.find_ids(query, models, options = {}) 
     204    get_index_for(*models).find_ids query, options.merge( :models => models ) 
     205  end 
     206 
     207  def self.find(query, models, options = {}, ar_options = {}) 
     208    # TODO generalize local/remote index so we can remove the workaround below 
     209    # (replace logic in class_methods#find_with_ferret) 
     210    if Class === models or models.size == 1 
     211      return (Class === models ? models : models.shift).find_with_ferret query, options, ar_options 
     212    end 
     213    index = get_index_for(*models) 
     214    multi = (MultiIndex === index or index.shared?) 
     215    if options[:per_page] 
     216      options[:page] = options[:page] ? options[:page].to_i : 1 
     217      limit = options[:per_page] 
     218      offset = (options[:page] - 1) * limit 
     219      if ar_options[:conditions] && !multi 
     220        ar_options[:limit] = limit 
     221        ar_options[:offset] = offset 
     222        options[:limit] = :all 
     223        options.delete :offset 
     224      else 
     225        # do pagination with ferret (or after everything is done in the case 
     226        # of multi_search) 
     227        options[:limit] = limit 
     228        options[:offset] = offset 
     229      end 
     230    elsif ar_options[:conditions] 
     231      if multi 
     232        # multisearch ignores find_options limit and offset 
     233        options[:limit] ||= ar_options.delete(:limit) 
     234        options[:offset] ||= ar_options.delete(:offset) 
     235      else 
     236        # let the db do the limiting and offsetting for single-table searches 
     237        unless options[:limit] == :all 
     238          ar_options[:limit] ||= options.delete(:limit) 
     239        end 
     240        ar_options[:offset] ||= options.delete(:offset) 
     241        options[:limit] = :all 
     242      end 
     243    end 
     244 
     245    total_hits, result = index.find_records query, options.merge(:models => models), ar_options 
     246    logger.debug "Query: #{query}\ntotal hits: #{total_hits}, results delivered: #{result.size}" 
     247    SearchResults.new(result, total_hits, options[:page], options[:per_page]) 
    201248  end 
    202249 
     
    258305  end 
    259306 
     307  # retrieves search result records from a data structure like this: 
     308  # { 'Model1' => { '1' => [ rank, score ], '2' => [ rank, score ] } 
     309  # 
     310  # TODO: in case of STI AR will filter out hits from other  
     311  # classes for us, but this 
     312  # will lead to less results retrieved --> scoping of ferret query 
     313  # to self.class is still needed. 
     314  # from the ferret ML (thanks Curtis Hatter) 
     315  # > I created a method in my base STI class so I can scope my query. For scoping 
     316  # > I used something like the following line: 
     317  # >  
     318  # > query << " role:#{self.class.eql?(Contents) '*' : self.class}" 
     319  # >  
     320  # > Though you could make it more generic by simply asking 
     321  # > "self.descends_from_active_record?" which is how rails decides if it should 
     322  # > scope your "find" query for STI models. You can check out "base.rb" in 
     323  # > activerecord to see that. 
     324  # but maybe better do the scoping in find_ids_with_ferret... 
     325  def self.retrieve_records(id_arrays, find_options = {}) 
     326    result = [] 
     327    # get objects for each model 
     328    id_arrays.each do |model, id_array| 
     329      next if id_array.empty? 
     330      model_class = begin 
     331        model.constantize 
     332      rescue 
     333        raise "Please use ':store_class_name => true' if you want to use multi_search.\n#{$!}" 
     334      end 
     335 
     336      # check for per-model conditions and take these if provided 
     337      if conditions = find_options[:conditions] 
     338        key = model.underscore.to_sym 
     339        conditions = conditions[key] if Hash === conditions 
     340      end 
     341 
     342      # merge conditions 
     343      conditions = combine_conditions([ "#{model_class.table_name}.#{model_class.primary_key} in (?)",  
     344                                        id_array.keys ],  
     345                                      conditions) 
     346 
     347 
     348      # check for include association that might only exist on some models in case of multi_search 
     349      filtered_include_options = [] 
     350      if include_options = find_options[:include] 
     351        include_options = [ include_options ] unless include_options.respond_to?(:each) 
     352        include_options.each do |include_option| 
     353          filtered_include_options << include_option if model_class.reflections.has_key?(include_option.is_a?(Hash) ? include_option.keys[0].to_sym : include_option.to_sym) 
     354        end 
     355      end 
     356      filtered_include_options = nil if filtered_include_options.empty? 
     357 
     358      # fetch 
     359      tmp_result = model_class.find(:all, find_options.merge(:conditions => conditions,  
     360                                                              :include    => filtered_include_options)) 
     361 
     362      # set scores and rank 
     363      tmp_result.each do |record| 
     364        record.ferret_rank, record.ferret_score = id_array[record.id.to_s] 
     365      end 
     366      # merge with result array 
     367      result.concat tmp_result 
     368    end 
     369     
     370    # order results as they were found by ferret, unless an AR :order 
     371    # option was given 
     372    result.sort! { |a, b| a.ferret_rank <=> b.ferret_rank } unless find_options[:order] 
     373    return result 
     374  end 
     375   
     376  # combine our conditions with those given by user, if any 
     377  def self.combine_conditions(conditions, additional_conditions = []) 
     378    returning conditions do 
     379      if additional_conditions && additional_conditions.any? 
     380        cust_opts = (Array === additional_conditions) ? additional_conditions.dup : [ additional_conditions ] 
     381        logger.debug "cust_opts: #{cust_opts.inspect}" 
     382        conditions.first << " and " << cust_opts.shift 
     383        conditions.concat(cust_opts) 
     384      end 
     385    end 
     386  end 
     387 
    260388  def self.build_field_config(fields) 
    261389    field_config = {} 
     
    304432    # other fields 
    305433    index_definition[:ferret_fields].each_pair do |field, options| 
     434      options = options.dup 
     435      options.delete :via 
     436      options.delete :boost if options[:boost].is_a?(Symbol) # dynamic boost 
    306437      fi.add_field(field, options) 
    307438    end 
     
    326457  def self.field_config_for(fieldname, options = {}) 
    327458    config = DEFAULT_FIELD_OPTIONS.merge options 
     459    config[:via] ||= fieldname 
    328460    config[:term_vector] = :no if config[:index] == :no 
    329     config.delete :via 
    330     config.delete :boost if config[:boost].is_a?(Symbol) # dynamic boosts aren't handled here 
    331461    return config 
    332462  end 
  • trunk/plugin/acts_as_ferret/lib/class_methods.rb

    r318 r319  
    141141    #               to explicitly state the fields you want to fetch, true won't 
    142142    #               work here) 
    143     # models::      only for single_index scenarios: an Array of other Model classes to  
    144     #               include in this search. Use :all to query all models. 
    145     # multi::       Specify additional model classes to search through. Each of 
    146     #               these, as well as this class, has to have the 
    147     #               :store_class_name option set to true. This option replaces the 
    148     #               multi_search method. 
    149143    # 
    150144    # +find_options+ is a hash passed on to active_record's find when 
     
    167161        limit = options[:per_page] 
    168162        offset = (options[:page] - 1) * limit 
    169         if find_options[:conditions] && !options[:multi] 
     163        if find_options[:conditions] 
    170164          find_options[:limit] = limit 
    171165          find_options[:offset] = offset 
     
    173167          options.delete :offset 
    174168        else 
    175           # do pagination with ferret (or after everything is done in the case 
    176           # of multi_search) 
     169          # do pagination with ferret 
    177170          options[:limit] = limit 
    178171          options[:offset] = offset 
    179172        end 
    180173      elsif find_options[:conditions] 
    181         if options[:multi] 
    182           # multisearch ignores find_options limit and offset 
    183           options[:limit] ||= find_options.delete(:limit) 
    184           options[:offset] ||= find_options.delete(:offset) 
    185         else 
    186           # let the db do the limiting and offsetting for single-table searches 
    187           unless options[:limit] == :all 
    188             find_options[:limit] ||= options.delete(:limit) 
    189           end 
    190           find_options[:offset] ||= options.delete(:offset) 
    191           options[:limit] = :all 
    192         end 
    193       end 
    194  
    195       total_hits, result = if options[:multi].blank? 
    196         find_records_lazy_or_not q, options, find_options 
    197       else 
    198         _multi_search q, options.delete(:multi), options, find_options 
    199       end 
     174        find_options[:limit] ||= options.delete(:limit) unless options[:limit] == :all 
     175        find_options[:offset] ||= options.delete(:offset) 
     176        options[:limit] = :all 
     177      end 
     178 
     179      total_hits, result = find_records_lazy_or_not q, options, find_options 
    200180      logger.debug "Query: #{q}\ntotal hits: #{total_hits}, results delivered: #{result.size}" 
    201181      SearchResults.new(result, total_hits, options[:page], options[:per_page]) 
    202182    end  
    203     alias find_by_contents find_with_ferret 
    204183 
    205184    
     
    211190    # 
    212191    def total_hits(q, options={}) 
    213       if options[:models] 
    214         # backwards compatibility 
    215         logger.warn "the :models option of total_hits is deprecated, please use :multi instead" 
    216         options[:multi] = options[:models]  
    217       end 
    218       if models = options[:multi] 
    219         options[:multi] = add_self_to_model_list_if_necessary(models).map(&:to_s) 
    220       end 
    221192      aaf_index.total_hits(q, options) 
    222193    end 
     
    229200    # 
    230201    # A block can be given too, it will be executed with every result: 
    231     # find_id_by_contents(q, options) do |model, id, score| 
     202    # find_ids_with_ferret(q, options) do |model, id, score| 
    232203    #    id_array << id 
    233204    #    scores_by_id[id] = score  
     
    236207    # instead of the [total_hits, results] array! 
    237208    #  
    238     def find_id_by_contents(q, options = {}, &block) 
    239       deprecated_options_support(options) 
    240       aaf_index.find_id_by_contents(q, options, &block) 
     209    def find_ids_with_ferret(q, options = {}, &block) 
     210      aaf_index.find_ids(q, options, &block) 
    241211    end 
    242212 
     
    248218    # be yielded, and the total number of hits is returned. 
    249219    def id_multi_search(query, additional_models = [], options = {}, &proc) 
    250       deprecated_options_support(options) 
     220      logger.warn "Model.id_multi_search is deprecated, use ActsAsFerret::find_ids instead!" 
    251221      models = add_self_to_model_list_if_necessary(additional_models) 
    252       aaf_index.id_multi_search(query, models.map(&:to_s), options, &proc) 
     222      ActsAsFerret::find_ids(query, models, options, &proc) 
    253223    end 
    254224     
    255225 
    256226    protected 
    257  
    258     def _multi_search(query, additional_models = [], options = {}, find_options = {}) 
    259       result = [] 
    260  
    261       rank = 0 
    262       if options[:lazy] 
    263         logger.warn "find_options #{find_options} are ignored because :lazy => true" unless find_options.empty? 
    264         total_hits = id_multi_search(query, additional_models, options) do |model, id, score, data| 
    265           result << FerretResult.new(model, id, score, rank += 1, data) 
    266         end 
    267       else 
    268         id_arrays = {} 
    269  
    270         limit = options.delete(:limit) 
    271