Class: DatastaxRails::Relation

Inherits:
Object
  • Object
show all
Includes:
Batches, FacetMethods, FinderMethods, ModificationMethods, SearchMethods, SpawnMethods, StatsMethods
Defined in:
lib/datastax_rails/relation.rb

Overview

rubocop:disable Style/ClassLength

Constant Summary collapse

MULTI_VALUE_METHODS =
%i(order where where_not fulltext greater_than less_than select stats field_facet
range_facet slow_order)
SINGLE_VALUE_METHODS =
%i(page per_page reverse_order query_parser consistency ttl use_solr escape group
allow_filtering)
SOLR_CHAR_RX =
/([\+\!\(\)\[\]\^\"\~\:\'\=\/]+)/
SOLR_DATE_REGEX =
/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z)/i

Constants included from FacetMethods

FacetMethods::BY_DAY, FacetMethods::BY_MONTH, FacetMethods::BY_YEAR

Constants included from StatsMethods

StatsMethods::STATS_FIELDS

Constants included from SpawnMethods

SpawnMethods::VALID_FIND_OPTIONS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from FacetMethods

#field_facet, #range_facet

Methods included from Batches

#find_each, #find_each_with_index, #find_in_batches

Methods included from StatsMethods

#average, #grouped_average, #grouped_maximum, #grouped_minimum, #grouped_stddev, #grouped_sum, #maximum, #minimum, #stddev, #sum

Methods included from SpawnMethods

#apply_finder_options, #except, #merge, #only

Methods included from FinderMethods

#find, #find_by, #find_by!, #first, #first!, #last, #last!

Methods included from ModificationMethods

#destroy, #destroy_all

Methods included from SearchMethods

#allow_filtering, #compute_stats, #consistency, #dont_escape, #extending, #fulltext, #greater_than, #group, #highlight, #less_than, #limit, #order, #page, #paginate, #query_parser, #reverse_order, #select, #slow_order, #solr_format, #where, #where_not, #with_cassandra, #with_solr

Constructor Details

#initialize(klass, column_family) ⇒ Relation

Initializes the Relation. Defaults page value to 1, per_page to the class default, and solr use to true. Everything else gets defaulted to nil or empty.

Parameters:

  • klass (Class)

    the child of DatastaxRails::Base that this relation searches

  • column_family (String, Symbol)

    the name of the column family this relation searches



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/datastax_rails/relation.rb', line 40

def initialize(klass, column_family)
  @klass, @column_family = klass, column_family
  @loaded = false
  @results = []
  @default_scoped = false
  @cql = DatastaxRails::Cql.for_class(klass)

  SINGLE_VALUE_METHODS.each { |v| instance_variable_set(:"@#{v}_value", nil) }
  MULTI_VALUE_METHODS.each { |v| instance_variable_set(:"@#{v}_values", []) }
  @highlight_options = {}
  @per_page_value = @klass.default_page_size
  @page_value = 1
  @use_solr_value = :default
  @extensions = []
  @create_with_value = {}
  @escape_value = :default
  @stats = {}
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object (protected)

:nodoc:



626
627
628
629
630
631
632
633
634
# File 'lib/datastax_rails/relation.rb', line 626

def method_missing(method, *args, &block) #:nodoc:
  if DatastaxRails::Collection.method_defined?(method)
    to_a.send(method, *args, &block)
  elsif @klass.respond_to?(method, true)
    scoping { @klass.send(method, *args, &block) }
  else
    super
  end
end

Instance Attribute Details

#column_familyObject (readonly)

Returns the value of attribute column_family.



30
31
32
# File 'lib/datastax_rails/relation.rb', line 30

def column_family
  @column_family
end

#cqlObject (readonly)

Returns the value of attribute cql.



30
31
32
# File 'lib/datastax_rails/relation.rb', line 30

def cql
  @cql
end

#create_with_valueObject

Returns the value of attribute create_with_value.



19
20
21
# File 'lib/datastax_rails/relation.rb', line 19

def create_with_value
  @create_with_value
end

#default_scopedObject Also known as: default_scoped?

Returns the value of attribute default_scoped.



19
20
21
# File 'lib/datastax_rails/relation.rb', line 19

def default_scoped
  @default_scoped
end

#highlight_optionsObject

Returns the value of attribute highlight_options.



20
21
22
# File 'lib/datastax_rails/relation.rb', line 20

def highlight_options
  @highlight_options
end

#klassObject (readonly)

Returns the value of attribute klass.



30
31
32
# File 'lib/datastax_rails/relation.rb', line 30

def klass
  @klass
end

#loadedObject (readonly) Also known as: loaded?

Returns the value of attribute loaded.



30
31
32
# File 'lib/datastax_rails/relation.rb', line 30

def loaded
  @loaded
end

Instance Method Details

#==(other) ⇒ Object

Returns true if the two relations have the same query parameters



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/datastax_rails/relation.rb', line 60

def ==(other)
  case other
  when Relation
    # This is not a valid implementation.  It's a placeholder till I figure out the right way.
    MULTI_VALUE_METHODS.each do |m|
      return false unless other.send("#{m}_values") == send("#{m}_values")
    end
    SINGLE_VALUE_METHODS.each do |m|
      return false unless other.send("#{m}_value") == send("#{m}_value")
    end
    return true
  when Array
    to_a == other
  end
end

#any?Boolean Also known as: exists?

Returns true if there are any results given the current criteria

Returns:

  • (Boolean)


77
78
79
80
81
82
83
# File 'lib/datastax_rails/relation.rb', line 77

def any?
  if block_given?
    to_a.any? { |*block_args| yield(*block_args) }
  else
    !empty?
  end
end

#cloneObject

Performs a deep copy using Marshal when cloning.



183
184
185
186
187
188
189
190
191
192
# File 'lib/datastax_rails/relation.rb', line 183

def clone
  dup.tap do |r|
    MULTI_VALUE_METHODS.each do |m|
      r.send("#{m}_values=", Marshal.load(Marshal.dump(send("#{m}_values"))))
    end
    SINGLE_VALUE_METHODS.each do |m|
      r.send("#{m}_value=", Marshal.load(Marshal.dump(send("#{m}_value")))) if send("#{m}_value")
    end
  end
end

#commit_solrObject

Sends a commit message to SOLR



596
597
598
# File 'lib/datastax_rails/relation.rb', line 596

def commit_solr
  rsolr.commit commit_attributes: {}
end

#countObject

Returns the total number of entries that match the given search. This means the total number of matches regardless of page size. If the relation has not been populated yet, a limit of 1 will be placed on the query before it is executed.

For a grouped query, this still returns the total number of matching documents

Compare with #size.



95
96
97
98
99
100
101
# File 'lib/datastax_rails/relation.rb', line 95

def count
  @count ||= if with_default_scope.path_decision == :solr
               with_default_scope.count_via_solr
             else
               with_default_scope.count_via_cql
             end
end

#count_via_cqlObject



288
289
290
291
292
293
294
295
296
# File 'lib/datastax_rails/relation.rb', line 288

def count_via_cql
  cql = @cql.select(['count(*)'])
  cql.using(@consistency_value) if @consistency_value
  @where_values.each do |wv|
    cql.conditions(wv)
  end
  cql.allow_filtering if @allow_filtering_value
  cql.execute.first['count']
end

#count_via_solrObject

Runs the query with a limit of 1 just to grab the total results attribute off the result set.



359
360
361
362
# File 'lib/datastax_rails/relation.rb', line 359

def count_via_solr
  results = limit(1).select(:id).to_a
  @group_value ? results.total_for_all : results.total_entries
end

#create(*args, &block) ⇒ Object

Create a new object with all of the criteria from this relation applied



233
234
235
# File 'lib/datastax_rails/relation.rb', line 233

def create(*args, &block)
  scoping { @klass.create(*args, &block) }
end

#create!(*args, &block) ⇒ Object

Like create but throws an exception on failure



238
239
240
# File 'lib/datastax_rails/relation.rb', line 238

def create!(*args, &block)
  scoping { @klass.create!(*args, &block) }
end

#current_pageObject

Returns the current page for will_paginate compatibility



109
110
111
# File 'lib/datastax_rails/relation.rb', line 109

def current_page
  page_value.try(:to_i)
end

#default_scopeObject

Gets a default scope with no conditions or search attributes set.



124
125
126
# File 'lib/datastax_rails/relation.rb', line 124

def default_scope
  klass.scoped.with_default_scope
end

#downcase_query(value) ⇒ Object

Everything that gets indexed into solr is downcased as part of the analysis phase. Normally, this is done to the query as well, but if your query includes wildcards then analysis isn’t performed. This means that the query does not get downcased. We therefore need to perform the downcasing ourselves. This does it while still leaving boolean operations (AND, OR, NOT, TO) and dates upcased.



606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
# File 'lib/datastax_rails/relation.rb', line 606

def downcase_query(value)
  # rubocop:disable Style/MultilineBlockChain
  if value.is_a?(String)
    value.split(/\bAND\b/).map do |a|
      a.split(/\bOR\b/).map do |o|
        o.split(/\bNOT\b/).map do |n|
          n.split(/\bTO\b/).map do |t|
            t.downcase
          end.join('TO')
        end.join('NOT')
      end.join('OR')
    end.join('AND').gsub(SOLR_DATE_REGEX) { Regexp.last_match[1].upcase }
  else
    value
  end
  # rubocop:enable Style/MultilineBlockChain
end

#empty?Boolean

Returns true if there are no results given the current criteria

Returns:

  • (Boolean)


139
140
141
142
143
144
# File 'lib/datastax_rails/relation.rb', line 139

def empty?
  return @results.empty? if loaded?

  c = count
  c.respond_to?(:zero?) ? c.zero? : c.empty?
end

#full_solr_range(attr) ⇒ Object



375
376
377
378
379
380
381
# File 'lib/datastax_rails/relation.rb', line 375

def full_solr_range(attr)
  if klass.attribute_definitions[attr]
    klass.attribute_definitions[attr].full_solr_range
  else
    '[\"\" TO *]'
  end
end

#initialize_copy(_other) ⇒ Object

Copies will have changes made to the criteria and so need to be reset.



177
178
179
180
# File 'lib/datastax_rails/relation.rb', line 177

def initialize_copy(_other)
  reset
  @search = nil
end

#inspect(just_me = false) ⇒ Object

Inspects the results of the search instead of the Relation itself. Passing true causes the Relation to be inspected.

Parameters:

  • just_me (Boolean) (defaults to: false)

    if true, inspect the Relation, otherwise the results



566
567
568
# File 'lib/datastax_rails/relation.rb', line 566

def inspect(just_me = false)
  just_me ? super() : to_a.inspect
end

#many?Boolean

Returns true if there are multiple results given the current criteria

Returns:

  • (Boolean)


147
148
149
150
151
152
153
# File 'lib/datastax_rails/relation.rb', line 147

def many?
  if block_given?
    to_a.many? { |*block_args| yield(*block_args) }
  else
    count > 1
  end
end

#map_cassandra_columns(conditions) ⇒ Object

If we index something into both cassandra and solr, we rename the cassandra column. This method maps the column names as necessary



276
277
278
279
280
281
282
283
284
285
286
# File 'lib/datastax_rails/relation.rb', line 276

def map_cassandra_columns(conditions)
  {}.tap do |mapped|
    conditions.each do |k, v|
      if (klass.attribute_definitions[k].indexed == :both)
        mapped["__#{k}"] = v
      else
        mapped[k] = v
      end
    end
  end
end

#new(*args, &block) ⇒ Object

Constructs a new instance of the class this relation points to with any criteria from this relation applied



157
158
159
# File 'lib/datastax_rails/relation.rb', line 157

def new(*args, &block)
  scoping { @klass.new(*args, &block) }
end

#next_pageObject

current_page + 1 or nil if there is no next page



119
120
121
# File 'lib/datastax_rails/relation.rb', line 119

def next_page
  current_page < total_pages ? (current_page + 1) : nil
end

#path_decisionObject



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'lib/datastax_rails/relation.rb', line 249

def path_decision
  return :cassandra if klass <= DatastaxRails::CassandraOnlyModel
  case use_solr_value
  when false
    return :cassandra
  when true
    return :solr
  else
    [order_values, where_not_values, fulltext_values, greater_than_values, less_than_values, field_facet_values,
     range_facet_values, group_value].each do |solr_only_stuff|
       return :solr unless solr_only_stuff.blank?
     end
    return :solr unless group_value.blank?
    return :solr unless page_value == 1
    @where_values.each do |wv|
      wv.each do |k, _v|
        next if klass.column_for_attribute(k).options[:cql_index]
        return :solr
      end
    end
    # If we get here, we can safely run this query via Cassandra
    return :cassandra
  end
end

#previous_pageObject

current_page - 1 or nil if there is no previous page



114
115
116
# File 'lib/datastax_rails/relation.rb', line 114

def previous_page
  current_page > 1 ? (current_page - 1) : nil
end

#query_via_cqlObject

Constructs a CQL query and runs it against Cassandra directly. For this to work, you need to run against either the primary key or a secondary index. For ad-hoc queries, you will have to use Solr.



301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
# File 'lib/datastax_rails/relation.rb', line 301

def query_via_cql
  select_columns =
    select_values.empty? ? (@klass.attribute_definitions.keys - @klass.lazy_attributes) : select_values.flatten
  cql = @cql.select((select_columns + [@klass.primary_key]).uniq)
  cql.using(@consistency_value) if @consistency_value
  @where_values.each do |wv|
    cql.conditions(Hash[wv.map { |k, v| [(k.to_s == 'id' ? @klass.primary_key : k), v] }])
  end
  @greater_than_values.each do |gtv|
    gtv.each do |k, v|
      # Special case if inequality is equal to the primary key (we're paginating)
      cql.paginate(v) if (k.to_s == @klass.primary_key)
    end
  end
  cql.limit(@per_page_value) if @per_page_value
  cql.allow_filtering if @allow_filtering_value
  results = []
  begin
    cql.execute.each do |row|
      results << @klass.instantiate(row[@klass.primary_key], row, select_columns)
    end
  rescue ::Cql::CqlError => e # TODO: Break out the various exception types
    # If we get an exception about an empty key, ignore it.  We'll return an empty set.
    if e.message =~ /Key may not be empty/
      # No-Op
    else
      raise
    end
  end
  if @slow_order_values.any?
    results.sort! do |a, b|
      values = slow_ordering(a, b)
      values[0] <=> values[1]
    end
  end
  results
end

#query_via_solrObject

Constructs a solr query to run against SOLR. At this point, only where, where_not, fulltext, order and pagination are supported. More will be added.

It’s also worth noting that where and where_not make use of individual filter_queries. If that’s not what you want, you might be better off constructing your own fulltext query and sending that in.

TODO: break this apart into multiple methods



391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
# File 'lib/datastax_rails/relation.rb', line 391

def query_via_solr # rubocop:disable all
  filter_queries = []
  orders = []
  @where_values.each do |wv|
    wv.each do |k, v|
      # If v is blank, check that there is no value for the field in the document
      filter_queries << (v.blank? ? "-#{k}:#{full_solr_range(k)}" : "#{k}:(#{v})")
    end
  end

  @where_not_values.each do |wnv|
    wnv.each do |k, v|
      # If v is blank, check for any value for the field in document
      filter_queries << (v.blank? ? "#{k}:#{full_solr_range(k)}" : "-#{k}:(#{v})")
    end
  end

  @greater_than_values.each do |gtv|
    gtv.each do |k, v|
      filter_queries << "#{k}:[#{v} TO *]"
    end
  end

  @less_than_values.each do |ltv|
    ltv.each do |k, v|
      filter_queries << "#{k}:[* TO #{v}]"
    end
  end

  @order_values.each do |ov|
    ov.each do |k, v|
      if @reverse_order_value
        orders << "#{k} #{v == :asc ? 'desc' : 'asc'}"
      else
        orders << "#{k} #{v == :asc ? 'asc' : 'desc'}"
      end
    end
  end

  sort = orders.join(',')

  q = @fulltext_values.empty? ? '*:*' : @fulltext_values.map { |ftv| '(' + ftv[:query] + ')' }.join(' AND ')

  params = { q: q }
  params[:sort] = sort
  params[:fq] = filter_queries unless filter_queries.empty?

  # Facets
  # facet=true to enable faceting,  facet.field=<field_name> (can appear more than once for multiple fields)
  # Additional options: f.<field_name>.facet.<option> [e.g. f.author.facet.sort=index]

  # Facet Fields
  unless field_facet_values.empty?
    params['facet'] = 'true'
    facet_fields = []
    field_facet_values.each do |facet|
      facet_field = facet[:field]
      facet_fields << facet_field
      facet[:options].each do |key, value|
        params["f.#{facet_field}.facet.#{key}"] = value.to_s
      end
    end
    params['facet.field'] = facet_fields
  end

  # Facet Ranges
  unless range_facet_values.empty?
    params['facet'] = 'true'
    facet_fields = []
    range_facet_values.each do |facet|
      facet_field = facet[:field]
      facet_fields << facet_field
      facet[:options].each do |key, value|
        params["f.#{facet_field}.facet.range.#{key}"] = value.to_s
      end
    end
    params['facet.range'] = facet_fields
  end

  if @highlight_options[:fields].present?
    params[:hl] = true
    params['hl.fl'] = @highlight_options[:fields]
    params['hl.snippets'] = @highlight_options[:snippets] if @highlight_options[:snippets]
    params['hl.fragsize'] = @highlight_options[:fragsize] if @highlight_options[:fragsize]
    if @highlight_options[:use_fast_vector]
      params['hl.useFastVectorHighlighter'] = true
      params['hl.tag.pre'] = @highlight_options[:pre_tag] if @highlight_options[:pre_tag].present?
      params['hl.tag.post'] = @highlight_options[:post_tag] if @highlight_options[:post_tag].present?
    else
      params['hl.mergeContiguous'] = @highlight_options[:merge_contiguous].present?
      params['hl.simple.pre'] = @highlight_options[:pre_tag] if @highlight_options[:pre_tag].present?
      params['hl.simple.post'] = @highlight_options[:post_tag] if @highlight_options[:post_tag].present?
    end
  end

  select_columns =
    select_values.empty? ? (@klass.attribute_definitions.keys - @klass.lazy_attributes) : select_values.flatten
  select_columns << @klass.primary_key
  select_columns.map! { |c| @klass.column_for_attribute(c).try(:type) == :map ? "#{c}*" : c.to_s }
  params[:fl] = select_columns.uniq.join(',')
  unless @stats_values.empty?
    params[:stats] = 'true'
    @stats_values.flatten.each do |sv|
      params['stats.field'] = sv
    end
    @params['stats.facet'] = @group_value
  end
  solr_response = nil
  if @group_value
    results = DatastaxRails::GroupedCollection.new
    params[:group] = 'true'
    params[:rows] = 10_000
    params['group.field'] = @group_value
    params['group.limit'] = @per_page_value
    params['group.offset'] = (@page_value - 1) * @per_page_value
    params['group.ngroups'] = 'false' # must be false due to issues with solr sharding
    solr_response = rsolr.post('select', data: params)
    response = solr_response['grouped'][@group_value.to_s]
    results.total_groups = response['groups'].size
    results.total_for_all = response['matches'].to_i
    results.total_entries = 0
    response['groups'].each do |group|
      results[group['groupValue']] = parse_docs(group['doclist'], select_columns)
      if results[group['groupValue']].total_entries > results.total_entries
        results.total_entries = results[group['groupValue']].total_entries
      end
    end
  else
    solr_response = rsolr.paginate(@page_value, @per_page_value, 'select', data: params, method: :post)
    response = solr_response['response']
    pp solr_response if ENV['DEBUG_SOLR'] == 'true'
    results = parse_docs(response, select_columns)
    results.highlights = solr_response['highlighting']
  end
  if solr_response['stats']
    @stats = solr_response['stats']['stats_fields'].with_indifferent_access
  end
  # Apply Facets if they exist
  if solr_response['facet_counts']
    results.facets = {}
    results.facets = results.facets.merge(solr_response['facet_counts']['facet_fields'].to_h)
    results.facets = results.facets.merge(solr_response['facet_counts']['facet_ranges'].to_h)
  end
  pp params if ENV['DEBUG_SOLR'] == 'true'
  results
end

#reloadObject

Reloads the results from cassandra or solr as appropriate



162
163
164
165
166
# File 'lib/datastax_rails/relation.rb', line 162

def reload
  reset
  to_a
  self
end

#resetObject

Empties out the current results. The next call to to_a will re-run the query.



170
171
172
173
174
# File 'lib/datastax_rails/relation.rb', line 170

def reset
  @loaded = @first = @last = @scope_for_create = @count = nil
  @stats = {}
  @results = []
end

#respond_to?(method, include_private = false) ⇒ Boolean

Override respond_to? so that it matches method_missing

Returns:

  • (Boolean)


243
244
245
246
247
# File 'lib/datastax_rails/relation.rb', line 243

def respond_to?(method, include_private = false)
  Array.method_defined?(method)                       ||
  @klass.respond_to?(method, include_private)         ||
  super
end

#scope_for_createObject

Creates a scope that includes all of the where values plus anything that is in create_with_value.



591
592
593
# File 'lib/datastax_rails/relation.rb', line 591

def scope_for_create
  @scope_for_create ||= where_values_hash.merge(create_with_value)
end

#scopingObject

Scope all queries to the current scope.

Example

Comment.where(:post_id => 1).scoping do
  Comment.first # SELECT * FROM comments WHERE post_id = 1
end

Please check unscoped if you want to remove all previous scopes (including the default_scope) during the execution of a block.



580
581
582
# File 'lib/datastax_rails/relation.rb', line 580

def scoping
  @klass.send(:with_scope, self, :overwrite) { yield }
end

#sizeObject

Returns the size of the total result set for the given criteria NOTE that this takes pagination into account so will only return the number of results in the current page. DatastaxRails models can have a default_page_size set which will cause them to be paginated all the time.

For a grouped query, this returns the size of the largest group.

Compare with #count



203
204
205
206
207
# File 'lib/datastax_rails/relation.rb', line 203

def size
  return @results.size if loaded? && !@group_value
  total_entries = count
  (per_page_value && total_entries > per_page_value) ? per_page_value : total_entries
end

#slow_ordering(obj1, obj2) ⇒ Object



339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
# File 'lib/datastax_rails/relation.rb', line 339

def slow_ordering(obj1, obj2)
  [[], []].tap do |values|
    i = 0
    @slow_order_values.each do |ordering|
      ordering.each do |k, v|
        if v == :asc
          values[0][i] = obj1.send(k)
          values[1][i] = obj2.send(k)
        else
          values[1][i] = obj1.send(k)
          values[0][i] = obj2.send(k)
        end
      end
      i += 1
    end
  end
end

#solr_escape(str) ⇒ Object

Escapes values that might otherwise mess up the URL or confuse SOLR. If you want to handle escaping yourself for a particular query then SearchMethods#dont_escape is what you’re looking for.



367
368
369
370
371
372
373
# File 'lib/datastax_rails/relation.rb', line 367

def solr_escape(str)
  if str.is_a?(String) && escape_value
    str.gsub(SOLR_CHAR_RX, '\\\\\1')
  else
    str
  end
end

#statsObject



103
104
105
106
# File 'lib/datastax_rails/relation.rb', line 103

def stats
  loaded? || to_a
  @stats
end

#to_aObject Also known as: all, results

Actually executes the query if not already executed. Returns a standard array thus no more methods may be chained.



218
219
220
221
222
223
224
225
226
227
228
# File 'lib/datastax_rails/relation.rb', line 218

def to_a
  return @results if loaded?
  if with_default_scope.path_decision == :solr
    @results = with_default_scope.query_via_solr
    @count = @group_value ? @results.total_for_all : @results.total_entries
  else
    @results = with_default_scope.query_via_cql
  end
  @loaded = true
  @results
end

#total_pagesObject

Returns the total number of pages required to display the results given the current page size. Used by will_paginate.



211
212
213
214
# File 'lib/datastax_rails/relation.rb', line 211

def total_pages
  return 1 unless @per_page_value
  (count / @per_page_value.to_f).ceil
end

#where_values_hashObject

Merges all of the where values together into a single hash



585
586
587
# File 'lib/datastax_rails/relation.rb', line 585

def where_values_hash
  where_values.reduce({}) { |a, e| a.merge(e) }
end

#with_default_scopeObject

:nodoc:



128
129
130
131
132
133
134
135
136
# File 'lib/datastax_rails/relation.rb', line 128

def with_default_scope #:nodoc:
  if default_scoped? && (default_scope = klass.send(:build_default_scope))
    default_scope = default_scope.merge(self)
    default_scope.default_scoped = false
    default_scope
  else
    self
  end
end