Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
grosser
committed
Dec 28, 2008
1 parent
03aa7a7
commit b48b7c5
Showing
6 changed files
with
163 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
PROBLEM | ||
======= | ||
- database :order=>'random' is slow | ||
- active record has no random build in | ||
|
||
SOLUTION | ||
======== | ||
- count all records | ||
- grab x records from rand(offset) | ||
|
||
INSTALL | ||
======= | ||
`script/plugin install git://github.com/grosser/random_records.git` | ||
|
||
USAGE | ||
===== | ||
|
||
Model.random(3) == [Model(id:112),Model(id:113),Model(id:114)] | ||
Model.random(1) == [Model(id:322)] | ||
Model.random == Model(id:234) | ||
|
||
AUTHOR | ||
====== | ||
Michael Grosser | ||
grosser.michael@gmail.com | ||
Hereby placed under public domain, do what you want, just do not hold me accountable... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
require 'rubygems' | ||
require 'spec' | ||
|
||
desc 'Default: run spec.' | ||
task :default => :spec | ||
|
||
desc "Run all specs in spec directory" | ||
task :spec do |t| | ||
options = "--colour --format progress --loadby --reverse" | ||
files = FileList['spec/**/*_spec.rb'] | ||
system("spec #{options} #{files}") | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
class ActiveRecord::Base | ||
def self.random(num=nil,options={}) | ||
return_array = !num.nil? | ||
num ||= 1 | ||
return [] if num.zero? | ||
num_records = options.delete(:count) || count | ||
highest_possible_offset = [0,num_records-num].max | ||
offset = [rand(num_records),highest_possible_offset].min | ||
limit = [num,num_records].min | ||
all = find(:all, {:offset => offset, :limit=>limit}.merge(options)) | ||
return_array ? all : all[0] | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
require File.expand_path("spec_helper", File.dirname(__FILE__)) | ||
|
||
describe :random do | ||
before :all do | ||
10.times {|i| User.create!} | ||
end | ||
|
||
it "finds a record when called without parameters" do | ||
User.random.class.should == User | ||
end | ||
it "finds a single random record" do | ||
User.random(1).size.should == 1 | ||
User.random(1)[0].class.should == User | ||
end | ||
it "finds by offset from rand" do | ||
User.expects(:rand).with(User.count).returns 3 | ||
User.random(1).should == [User.find(4)] | ||
end | ||
it "finds using the given count option" do | ||
User.expects(:rand).with(3).returns 2 | ||
User.random(1,:count=>3).should == [User.find(3)] | ||
end | ||
it "finds the requested number" do | ||
User.random(9).uniq.size.should == 9 | ||
end | ||
it "finds sequentially from offset" do | ||
users = User.random(9).map(&:id) | ||
users.each_with_index do |id,index| | ||
next if index.zero? | ||
id.should == (users[index-1] + 1) | ||
end | ||
end | ||
it "finds count records when requested >= count" do | ||
User.random(20).size.should == User.count | ||
end | ||
it "returns empty array if number is 0" do | ||
User.random(0).should == [] | ||
end | ||
it "is chainable" do | ||
User.first_5.random(9).size.should == 5 | ||
User.first_5.random(4).size.should == 4 | ||
end | ||
end | ||
|
||
describe 'when no records exist' do | ||
before :all do | ||
User.delete_all | ||
end | ||
it 'finds nil without parameters' do | ||
User.random.should == nil | ||
end | ||
it "finds 0 for all calls" do | ||
User.random(20).size.should == 0 | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
require 'rubygems' | ||
require 'active_record' | ||
|
||
#create model table | ||
ActiveRecord::Schema.define(:version => 1) do | ||
create_table "users" do |t| | ||
t.integer :age | ||
t.timestamps | ||
end | ||
end | ||
|
||
#create model | ||
class User < ActiveRecord::Base | ||
named_scope :first_5, :conditions=>"id < 6" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# ---- requirements | ||
require 'rubygems' | ||
require 'spec' | ||
require 'mocha' | ||
|
||
$LOAD_PATH << File.expand_path("../lib", File.dirname(__FILE__)) | ||
|
||
|
||
# ---- rspec | ||
Spec::Runner.configure do |config| | ||
config.mock_with :mocha | ||
end | ||
|
||
|
||
# ---- bugfix | ||
#`exit?': undefined method `run?' for Test::Unit:Module (NoMethodError) | ||
#can be solved with require test/unit but this will result in extra test-output | ||
module Test | ||
module Unit | ||
def self.run? | ||
true | ||
end | ||
end | ||
end | ||
|
||
# ---- load active record | ||
require 'active_record' | ||
|
||
|
||
RAILS_ENV = "test" | ||
ActiveRecord::Base.configurations = {"test" => { | ||
:adapter => "sqlite3", | ||
:database => ":memory:", | ||
}.with_indifferent_access} | ||
|
||
ActiveRecord::Base.logger = Logger.new(File.directory?("log") ? "log/#{RAILS_ENV}.log" : "/dev/null") | ||
ActiveRecord::Base.establish_connection(:test) | ||
|
||
|
||
# ---- setup environment/plugin | ||
require File.expand_path("../init", File.dirname(__FILE__)) | ||
load File.expand_path("setup_test_model.rb", File.dirname(__FILE__)) |