0.0
No commit activity in last 3 years
No release in over 3 years
ActiveRecord extension for weighted randomization which supplies loading records with weight for randomize into database and weighted randomization of them
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

>= 0
 Project Readme

Weighted Random¶ ↑

Weighted randomization extension for ActiveRecord.

Gives ability to get weighted random record from particular database relation.

Installation¶ ↑

Gem¶ ↑

gem 'weighted_random'

Model¶ ↑

Generate model with weight and cumulative_weight integer attributes:

rails g model your_model [your_attributes] weight:integer cumulative_weight:integer

Or add these two attributes into migration of existing model:

create_table :your_table, do |t|
  t.integer :weight
  t.integer :cumulative_weight
end

It is a good idea to add index on cumulative_weight attribute:

add_index :your_table, :cumulative_weight

Based on Benchmark.bmbm times, it makes creating of records 2 times faster and getting a random record 11 times faster!

Finally, load weighted randomization stuff into desired model and set accessibillity of weight attribute:

class YourModel < ActiveRecord::Base
  weighted_randomizable
  attr_accessible :weight
end

Usage¶ ↑

Importing data¶ ↑

Just create records, each must contain weight value:

LastName.create [
  {:name => 'Smith',    :weight => 10},
  {:name => 'Johnson',  :weight => 8},
  {:name => 'Williams', :weight => 7},
  {:name => 'Jones',    :weight => 6},
  {:name => 'Brown',    :weight => 6},
  {:name => 'Davis',    :weight => 5},
  {:name => 'Miller',   :weight => 4},
  {:name => 'Wilson',   :weight => 3}
]

It automatically sets cumulative_weight attribute for each record.

Here is an example of importing data from CSV file:

db/seeds/last_names.csv:

name,weight
Smith,10
Johnson,8
Williams,7
Jones,6
Brown,6
Davis,5
Miller,4
Wilson,3

db/seeds.rb:

LastName.create(
  CSV.table(File.expand_path('seeds/last_names.csv', File.dirname(__FILE__))).collect(&:to_hash)
)

Weighted randomization¶ ↑

To get weighed random record simply run:

LastName.weighted_rand

Demonstration:

10.times { puts LastName.weighted_rand.name }
Johnson
Brown
Johnson
Smith
Smith
Jones
Smith
Williams
Miller
Jones

Author¶ ↑

Szymon Przybył (github.com/apocalyptiq)