Module: Randumb::ActiveRecord::Relation

Included in:
ActiveRecord::Relation
Defined in:
lib/randumb/relation.rb

Instance Method Summary collapse

Instance Method Details

#order_by_rand(opts = {}) ⇒ Object



66
67
68
69
70
71
72
73
74
75
# File 'lib/randumb/relation.rb', line 66

def order_by_rand(opts = {})
  if opts.is_a?(Hash)
    build_order_scope(opts)
  else
    raise ArgumentError.new(
      "order_by_rand() expects a hash of options.  If you need to limit "\
      "results simply add a limit to your scope ex: Artist.order_by_rand.limit(1)"
    )
  end
end

#order_by_rand_weighted(ranking_column, opts = {}) ⇒ Object



77
78
79
80
81
# File 'lib/randumb/relation.rb', line 77

def order_by_rand_weighted(ranking_column, opts={})
  raise_unless_valid_ranking_column(ranking_column)
  is_randumb_postges_case?(self, ranking_column)
  build_order_scope(opts, ranking_column)
end

#random(max_items = nil, opts = {}) ⇒ Object

If the max_items argument is omitted, one random entity will be returned. If you provide the integer argument, you will get back an array of records.



12
13
14
15
16
17
18
19
20
21
22
# File 'lib/randumb/relation.rb', line 12

def random(max_items = nil, opts={})
  ActiveSupport::Deprecation.warn "The random() method will be depricated in randumb 1.0 in favor of the order_by_rand scope."
  relation = clone
  return random_by_id_shuffle(max_items, opts) if is_randumb_postges_case?(relation)
  scope = relation.order_by_rand(opts)

  scope = scope.limit(max_items) if override_limit?(max_items, relation)

  # return first record if method was called without parameters
  max_items ? scope.to_a : scope.first
end

#random_by_id_shuffle(max_items = nil, opts = {}) ⇒ Object

This was my first implementation, adding it as an option for people to use and to fall back on for pesky DB one off situations…

https://github.com/spilliton/randumb/issues/7


45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/randumb/relation.rb', line 45

def random_by_id_shuffle(max_items = nil, opts={})
  return_first_record = max_items.nil? # see return switch at end
  max_items ||= 1
  relation = clone
  ids = fetch_random_ids(relation, max_items, opts)

  # build new scope for final query
  the_scope = klass.includes(includes_values)

  # specifying empty selects caused bug in rails 3.0.0/3.0.1
  the_scope = the_scope.select(select_values) unless select_values.empty?

  # get the records and shuffle since the order of the ids
  # passed to where() isn't retained in the result set
  rng = random_number_generator(opts)
  records = the_scope.where(:id => ids).to_a.shuffle!(:random => rng)

  # return first record if method was called without parameters
  return_first_record ? records.first : records
end

#random_weighted(ranking_column, max_items = nil, opts = {}) ⇒ Object

If ranking_column is provided, that named column wil be multiplied by a random number to determine probability of order. The ranking column must be numeric.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/randumb/relation.rb', line 26

def random_weighted(ranking_column, max_items = nil, opts={})
  ActiveSupport::Deprecation.warn "The random_weighted() method will be depricated in randumb 1.0 in favor of the order_by_rand_weighted scope."
  relation = clone
  return random_by_id_shuffle(max_items, opts) if is_randumb_postges_case?(relation, ranking_column)
  raise_unless_valid_ranking_column(ranking_column)

  scope = relation.order_by_rand_weighted(ranking_column, opts)

  # override the limit if they are requesting multiple records
  scope = scope.limit(max_items) if override_limit?(max_items, relation)

  # return first record if method was called without parameters
  max_items ? scope.to_a : scope.first
end