Module: Mongoid::Mebla::ClassMethods

Defined in:
lib/mebla/mongoid/mebla.rb

Overview

Defines class methods for Mongoid::Mebla

Instance Method Summary collapse

Instance Method Details

#search(query = "") ⇒ Mebla::Search

Searches the model using Slingshot search DSL

Search for all posts with a field ‘title’ of value ‘Testing Search’

Post.search “title: Testing Search”

Parameters:

  • query (String) (defaults to: "")

    a string representing the search query

Returns:



183
184
185
# File 'lib/mebla/mongoid/mebla.rb', line 183

def search(query = "")
  ::Mebla.search(query, self.slingshot_type_name)
end

#search_in(*opts) ⇒ nil

Defines which fields should be indexed and searched

Defines a search index on a normal document with custom mappings on “body”

class Document

include Mongoid::Document
include Mongoid::Mebla
field :title
field :body
field :publish_date, :type => Date
#...
search_in :title, :publish_date, :body => { :boost => 2.0, :analyzer => 'snowball' }

end

Defines a search index on a normal document with an index on a field inside a relation

class Document

include Mongoid::Document
include Mongoid::Mebla
field :title
field :body
field :publish_date, :type => Date

referenced_in :blog  
#...
# relations mappings are detected automatically
search_in :title, :publish_date, :body => { :boost => 2.0, :analyzer => 'snowball' }, :search_relations => {
  :blog => [:author, :name]
}

end

Defines a search index on a normal document with an index on method “permalink”

class Document

include Mongoid::Document
include Mongoid::Mebla
field :title
field :body
field :publish_date, :type => Date

def permalink
  self.title.gsub(/\s/, "-").downcase
end      
#...
# methods can also define custom mappings if needed
search_in :title, :publish_date, :permalink, :body => { :boost => 2.0, :analyzer => 'snowball' }

end

Defines a search index on an embedded document with a single parent and custom mappings on “body”

class Document

include Mongoid::Document
include Mongoid::Mebla
field :title
field :body
field :publish_date, :type => Date
#...
embedded_in :category
search_in :title, :publish_date, :body => { :boost => 2.0, :analyzer => 'snowball' }, :embedded_in => :category

end

Parameters:

  • fields (*opts)

Returns:

  • (nil)


104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/mebla/mongoid/mebla.rb', line 104

def search_in(*opts)        
  # Extract advanced indeces
  options = opts.extract_options!.symbolize_keys
  # Extract simple indeces
  attrs = opts.flatten
  
  
  # If this document is embedded check for the embedded_in option and raise an error if none is specified
  # Example::
  #  embedded in a regular class (e.g.: using the default convention for naming the foreign key)
  #    :embedded_in => :parent        
  if self.embedded?          
    if (embedor = options.delete(:embedded_in))
      relation = self.relations[embedor.to_s]
      
      # Infer the attributes of the relation
      self.embedded_parent = relation.class_name.constantize
      self.embedded_parent_foreign_key = relation.key.to_s
      self.embedded_as = relation[:inverse_of] || relation.inverse_setter.to_s.gsub(/=$/, '')
      
      if self.embedded_as.blank?
        raise ::Mebla::Errors::MeblaConfigurationException.new("Couldn't infer #{embedor.to_s} inverse relation, please set :inverse_of option on the relation.")
      end
    else
      raise ::Mebla::Errors::MeblaConfigurationException.new("#{self.name} is embedded: embedded_in option should be set to the parent class if the document is embedded.")
    end
  end
  
  self.search_relations = {}
  # Keep track of relational indecies
  unless (relations_inedcies = options.delete(:search_relations)).nil?
    relations_inedcies.each do |relation, index|
      self.search_relations[relation] = index
    end
  end
  
  # Keep track of searchable fields (for indexing)
  self.search_fields = attrs + options.keys        
  
  # Generate simple indeces' mappings
  attrs_mappings = {}
  
  attrs.each do |attribute|
    unless (attr_field = self.fields[attribute.to_s]).nil?
      unless (field_type = attr_field.type.to_s) == "Array" # arrays don't need mappings
        attrs_mappings[attribute] = {:type => SLINGSHOT_TYPE_MAPPING[field_type] || "string"}
      end
    else
      attrs_mappings[attribute] = {:type => "string"}
    end
  end
  
  # Generate advanced indeces' mappings
  opts_mappings = {}
  
  options.each do |opt, properties|
    unless (attr_field = self.fields[opt.to_s]).nil?
      unless (field_type = attr_field.type.to_s) == "Array"
        opts_mappings[opt] = {:type => SLINGSHOT_TYPE_MAPPING[field_type] || "string" }.merge!(properties)
      end
    else
      opts_mappings[opt] = {:type => "string"}.merge!(properties)                
    end
  end
  
  # Merge mappings
  self.slingshot_mappings = {}.merge!(attrs_mappings).merge!(opts_mappings)        
  
  # Keep track of indexed models (for bulk indexing)
  ::Mebla.context.add_indexed_model(self, self.slingshot_type_name.to_sym => prepare_mappings)
end

#slingshot_type_nameString

Retrieves the type name of the model (used to populate the _type variable while indexing)

Returns:

  • (String)


190
191
192
# File 'lib/mebla/mongoid/mebla.rb', line 190

def slingshot_type_name
  "#{self.name.underscore}"        
end

#sub_class?Boolean

Checks if the class is a subclass

Returns:

  • (Boolean)

    true if class is a subclass



212
213
214
# File 'lib/mebla/mongoid/mebla.rb', line 212

def sub_class?
  self.superclass != Object
end

#without_indexing(&block) ⇒ nil

Note:

you can skip indexing to create, update or delete records without affecting the index

Enables the modification of records without indexing

Example

create record without it being indexed

Class.without_indexing do
  create :title => "This is not indexed", :body => "Nothing will be indexed within this block"      
end

Returns:

  • (nil)


202
203
204
205
206
207
208
# File 'lib/mebla/mongoid/mebla.rb', line 202

def without_indexing(&block)
  skip_callback(:save, :after, :add_to_index)
  skip_callback(:destroy, :before, :remove_from_index)
  yield
  set_callback(:save, :after, :add_to_index)
  set_callback(:destroy, :before, :remove_from_index)
end