Skip to content

Commit

Permalink
Merge pull request #47 from tmwh/master
Browse files Browse the repository at this point in the history
Method as keyword (not only fields)
  • Loading branch information
mauriciozaffari committed Feb 15, 2013
2 parents ba4df9f + 1e7b6b0 commit 9bcc7cb
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 31 deletions.
5 changes: 2 additions & 3 deletions lib/mongoid_search/mongoid_search.rb
Expand Up @@ -124,8 +124,7 @@ def index_keywords!

private
def set_keywords
self._keywords = self.search_fields.map do |field|
Mongoid::Search::Util.keywords(self, field)
end.flatten.reject{|k| k.nil? || k.empty?}.uniq.sort
self._keywords = Mongoid::Search::Util.keywords(self, self.search_fields).
flatten.reject{|k| k.nil? || k.empty?}.uniq.sort
end
end
40 changes: 17 additions & 23 deletions lib/mongoid_search/util.rb
@@ -1,35 +1,29 @@
# encoding: utf-8
module Mongoid::Search::Util

def self.keywords(klass, field)
if field.is_a?(Hash)
field.keys.map do |key|
attribute = klass.send(key)
def self.keywords(klass, fields)
if fields.is_a?(Array)
fields.map do |field|
self.keywords(klass, field)
end
elsif fields.is_a?(Hash)
fields.keys.map do |field|
attribute = klass.send(field)
unless attribute.blank?
method = field[key]
if attribute.is_a?(Array)
if method.is_a?(Array)
method.map {|m| attribute.map { |a| normalize_keywords a.send(m) } }
else
attribute.map(&method).map { |t| normalize_keywords t }
end
elsif attribute.is_a?(Hash)
if method.is_a?(Array)
method.map {|m| normalize_keywords attribute[m.to_sym] }
else
normalize_keywords(attribute[method.to_sym])
end
attribute.map{ |a| self.keywords(a, fields[field]) }
else
if method.is_a?(Array)
method.map {|m| normalize_keywords attribute[m.to_sym] }
else
normalize_keywords(attribute.send(method))
end
self.keywords(attribute, fields[field])
end
end
end
else
value = klass.send(field)
value = if klass.respond_to?(fields.to_s + "_translations")
klass.send(fields.to_s + "_translations").values
elsif klass.respond_to?(fields)
klass.send(fields)
else
value = klass[fields];
end
value = value.join(' ') if value.respond_to?(:join)
normalize_keywords(value) if value
end
Expand Down
2 changes: 1 addition & 1 deletion spec/models/category.rb
@@ -1,6 +1,6 @@
class Category
include Mongoid::Document
field :name
field :name, localize: true
field :description

has_many :products
Expand Down
8 changes: 8 additions & 0 deletions spec/models/tag.rb
@@ -1,6 +1,14 @@
class Tag
include Mongoid::Document
include Mongoid::Search

field :name

belongs_to :product

def title
self.name
end

search_in :title, :product => [:name, { :info => [ :summary, :description ], :category => [:name, :description]}]
end
3 changes: 2 additions & 1 deletion spec/models/variant.rb
@@ -1,4 +1,5 @@
autoload :Product, "models/product.rb"
class Variant < Product
field :color
search_in :color
end
end
31 changes: 28 additions & 3 deletions spec/mongoid_search_spec.rb
Expand Up @@ -19,7 +19,7 @@
Mongoid::Search.stem_proc = @default_proc
@product = Product.create :brand => "Apple",
:name => "iPhone",
:tags => ["Amazing", "Awesome", "Olé"].map { |tag| Tag.new(:name => tag) },
:tags => (@tags = ["Amazing", "Awesome", "Olé"].map { |tag| Tag.new(:name => tag) }),
:category => Category.new(:name => "Mobile", :description => "Reviews"),
:subproducts => [Subproduct.new(:brand => "Apple", :name => "Craddle")],
:info => { :summary => "Info-summary",
Expand Down Expand Up @@ -79,6 +79,7 @@
its(:_keywords) { should == ["apple", "iphone"] }
end


it "should set the _keywords field for array fields also" do
@product.attrs = ['lightweight', 'plastic', :red]
@product.save!
Expand Down Expand Up @@ -136,7 +137,6 @@
@product._keywords.should == ["1908", "amazing", "car", "first", "ford", "vehicle"]
end


it "should return results in search" do
Product.full_text_search("apple").size.should == 1
end
Expand Down Expand Up @@ -202,7 +202,7 @@
end

it 'should return the classes that include the search module' do
Mongoid::Search.classes.should == [Product]
Mongoid::Search.classes.should == [Product, Tag]
end

it 'should have a method to index keywords' do
Expand Down Expand Up @@ -245,4 +245,29 @@
Product.full_text_search('apple imac').map(&:relevance).should == [2, 1]
end
end

context "when using methods for keywords" do
it "should set the _keywords from methods" do
@tags.first._keywords.should include "amazing"
end
end

context "when using deeply nested fields for keywords" do
context "when explicitly calling set_keywords" do
it "should set the _keywords from parent" do
@tags.first.send(:set_keywords)
@tags.first._keywords.should == ["amazing", "description", "info", "iphone", "mobile", "reviews", "summary"]
end
end
end

context "when using localized fields" do
it "should set the keywords from all localizations" do
@product = Product.create :brand => "Ford",
:name => "T 1908",
:tags => ["Amazing", "First", "Car"].map { |tag| Tag.new(:name => tag) },
:category => Category.new(:name_translations => { :en => "Vehicle", :de => "Fahrzeug" })
@product._keywords.should include("fahrzeug")
end
end
end

0 comments on commit 9bcc7cb

Please sign in to comment.