Module: ThinkingSphinx::ActiveRecord::ClassMethods

Defined in:
lib/thinking_sphinx/active_record.rb

Instance Method Summary collapse

Instance Method Details

#add_sphinx_index(name, &block) ⇒ Object



194
195
196
197
198
199
200
201
# File 'lib/thinking_sphinx/active_record.rb', line 194

def add_sphinx_index(name, &block)
  index = ThinkingSphinx::Index::Builder.generate self, name, &block

  unless sphinx_indexes.any? { |i| i.name == index.name }
    add_sphinx_callbacks_and_extend(index.delta?)
    insert_sphinx_index index
  end
end

#core_index_namesObject



227
228
229
230
# File 'lib/thinking_sphinx/active_record.rb', line 227

def core_index_names
  define_indexes
  sphinx_indexes.collect(&:core_name)
end

#define_index(name = nil, &block) ⇒ Object

Allows creation of indexes for Sphinx. If you don’t do this, there isn’t much point trying to search (or using this plugin at all, really).

An example or two:

define_index
  indexes :id, :as => :model_id
  indexes name
end

You can also grab fields from associations - multiple levels deep if necessary.

define_index do
  indexes tags.name, :as => :tag
  indexes articles.content
  indexes orders.line_items.product.name, :as => :product
end

And it will automatically concatenate multiple fields:

define_index do
  indexes [author.first_name, author.last_name], :as => :author
end

The #indexes method is for fields - if you want attributes, use #has instead. All the same rules apply - but keep in mind that attributes are for sorting, grouping and filtering, not searching.

define_index do
  # fields ...

  has created_at, updated_at
end

One last feature is the delta index. This requires the model to have a boolean field named ‘delta’, and is enabled as follows:

define_index do
  # fields ...
  # attributes ...

  set_property :delta => true
end

Check out the more detailed documentation for each of these methods at ThinkingSphinx::Index::Builder.



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/thinking_sphinx/active_record.rb', line 149

def define_index(name = nil, &block)
  self.sphinx_index_blocks ||= []
  self.sphinx_indexes      ||= []
  self.sphinx_facets       ||= []

  ThinkingSphinx.context.add_indexed_model self

  if sphinx_index_blocks.empty?
    before_validation :define_indexes
    before_destroy    :define_indexes
  end

  self.sphinx_index_blocks << lambda {
    add_sphinx_index name, &block
  }

  #include ThinkingSphinx::ActiveRecord::Scopes
  #include ThinkingSphinx::SearchMethods
end

#define_indexesObject



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/thinking_sphinx/active_record.rb', line 169

def define_indexes
  superclass.define_indexes unless superclass == ::ActiveRecord::Base

  return if sphinx_index_blocks.nil? ||
    defined_indexes?                 ||
    !ThinkingSphinx.define_indexes?

  sphinx_index_blocks.each do |block|
    block.call
  end

  self.defined_indexes = true

  # We want to make sure that if the database doesn't exist, then Thinking
  # Sphinx doesn't mind when running non-TS tasks (like db:create, db:drop
  # and db:migrate). It's a bit hacky, but I can't think of a better way.
rescue StandardError => err
  case err.class.name
  when "Mysql::Error", "Java::JavaSql::SQLException", "ActiveRecord::StatementInvalid"
    return
  else
    raise err
  end
end

#delete_in_index(index, document_id) ⇒ Object



259
260
261
262
263
264
265
266
267
268
# File 'lib/thinking_sphinx/active_record.rb', line 259

def delete_in_index(index, document_id)
  return unless ThinkingSphinx.sphinx_running? &&
    search_for_id(document_id, index)

  ThinkingSphinx::Configuration.instance.client.update(
    index, ['sphinx_deleted'], {document_id => [1]}
  )
rescue Riddle::ConnectionError, ThinkingSphinx::SphinxError
  # Not the end of the world if Sphinx isn't running.
end

#delta_index_namesObject



232
233
234
235
# File 'lib/thinking_sphinx/active_record.rb', line 232

def delta_index_names
  define_indexes
  sphinx_indexes.select(&:delta?).collect(&:delta_name)
end

#delta_indexed_by_sphinx?Boolean

Returns:

  • (Boolean)


218
219
220
# File 'lib/thinking_sphinx/active_record.rb', line 218

def delta_indexed_by_sphinx?
  sphinx_indexes && sphinx_indexes.any? { |index| index.delta? }
end

#has_sphinx_indexes?Boolean

Returns:

  • (Boolean)


208
209
210
211
212
# File 'lib/thinking_sphinx/active_record.rb', line 208

def has_sphinx_indexes?
  sphinx_indexes      &&
  sphinx_index_blocks &&
  (sphinx_indexes.length > 0 || sphinx_index_blocks.length > 0)
end

#indexed_by_sphinx?Boolean

Returns:

  • (Boolean)


214
215
216
# File 'lib/thinking_sphinx/active_record.rb', line 214

def indexed_by_sphinx?
  sphinx_indexes && sphinx_indexes.length > 0
end

#insert_sphinx_index(index) ⇒ Object



203
204
205
206
# File 'lib/thinking_sphinx/active_record.rb', line 203

def insert_sphinx_index(index)
  self.sphinx_indexes << index
  descendants.each { |klass| klass.insert_sphinx_index(index) }
end

#source_of_sphinx_indexObject



246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/thinking_sphinx/active_record.rb', line 246

def source_of_sphinx_index
  define_indexes
  possible_models = self.sphinx_indexes.collect { |index| index.model }
  return self if possible_models.include?(self)

  parent = self.superclass
  while !possible_models.include?(parent) && parent != ::ActiveRecord::Base
    parent = parent.superclass
  end

  return parent
end

#sphinx_index_namesObject



222
223
224
225
# File 'lib/thinking_sphinx/active_record.rb', line 222

def sphinx_index_names
  define_indexes
  sphinx_indexes.collect(&:all_names).flatten
end

#sphinx_offsetObject



270
271
272
273
# File 'lib/thinking_sphinx/active_record.rb', line 270

def sphinx_offset
  ThinkingSphinx.context.superclass_indexed_models.
    index eldest_indexed_ancestor
end

#to_riddleObject



237
238
239
240
241
242
243
244
# File 'lib/thinking_sphinx/active_record.rb', line 237

def to_riddle
  define_indexes
  sphinx_database_adapter.setup

  local_sphinx_indexes.collect { |index|
    index.to_riddle(sphinx_offset)
  }.flatten
end