random_order 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 85869c402378af9d2b328e80a04f2324bf044ffbabbaed80909e52f37ba3957f
4
- data.tar.gz: 5d6ee714b7f0311a88f7ed34134b655dec57ece3543e8a9e1c26ce5468ef4917
3
+ metadata.gz: 44c17e681b84961986ec40faa61117db2eebe889be510822c905bbed642cffa1
4
+ data.tar.gz: 6c180250b563a70cff7aaca0aca869cc845e06a67a9e8f99217b8c18cec99d06
5
5
  SHA512:
6
- metadata.gz: 6b02bb4634682f6872a708be802b7f44b1bafa9ce72a876c6a29f57bb5154653608d609519f1045e67d4f8082c7f23619ed66f826ac947f735f1d8f7c66ba536
7
- data.tar.gz: 85796b4d178f8ea035773829df8b8a7a7f8e15bd5f632f7ab01b204f479b44d91b630810e5a34d04262dd761d7eca6ee7c317400b5439bef2acf691ce4e875e2
6
+ metadata.gz: 4284befb9765296e151379f4ab765bcfbae71168e2625f2367af371d862f3673c829dbbe33cfb0bd11f94816a4e86afc9ffca468326c7f958efbc2bcf22be672
7
+ data.tar.gz: a40069226504d3f50a353d146735a6fe00c1e71e49d683146fca0538463e5ed713a9f7e5e3fc0e8bc8aa5e220719a411c0adff87fcb7a35627cd9b6ffad72f22
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # RandomOrder
2
- This gem could DRY your code and return random relation objects or instance object.
2
+ With this gem, you can return a random record from the database using SQL or use `random scope` to return records in random order.
3
3
 
4
4
  ## Usage
5
- Works with `MySQL`, `SQLite`, `PostgreSQL`
5
+ Works with `MySQL`, `SQLite`, `PostgreSQL`.
6
6
 
7
- This gem is adding three methods to ActiveRecord Relations - `random` , `find_random` and `find_many_random(...)`.
7
+ This gem is adding three methods to ActiveRecord Relations - `random` , `find_random` and `find_many_random(...)`, `fast_random(n = 1)`.
8
8
 
9
9
  You can do the following:
10
10
  ```ruby
@@ -12,19 +12,44 @@ u1 = User.create(name: 'Lilith')
12
12
  u2 = User.create(name: 'Metamorph')
13
13
  u3 = User.create(name: 'Diablo')
14
14
 
15
- assert_equal User.find_random.is_a?(User), true
16
15
  assert_equal User.random.is_a?(ActiveRecord::Relation), true
17
16
  assert_equal User.find_many_random(10).is_a?(ActiveRecord::Relation), true
17
+ assert_equal User.fast_random.is_a?(ActiveRecord::Relation), true
18
+ assert_equal User.find_random.is_a?(User), true
19
+ ```
20
+ ## Fast Random method
21
+ As you may know `order by RANDOM()` might be slow in case you have many records in DB. I think the case I suggest to use another method which is bundled with this gem fast_random which is using another SQL to return random records from DB. It has some limitations like your table must have a primary key column.
22
+ Simple benchmark on the table with `88000 records` shows that it's `20` times faster. See screenshot with logs below:
23
+
24
+ ```ruby
25
+ n = 10
26
+ Benchmark.bm do |benchmark|
27
+ benchmark.report("find_many_random(100)") do
28
+ n.times do
29
+ Business.find_many_random(100).to_a
30
+ end
31
+ end
32
+ benchmark.report("fast_random(100)") do
33
+ n.times do
34
+ Business.fast_random(100).to_a
35
+ end
36
+ end
37
+ end
38
+ #
39
+ user system total real
40
+ find_many_random(100) 0.088990 0.025837 0.114827 ( 13.836576)
41
+ fast_random(100) 0.060209 0.013933 0.074142 ( 0.699557)
18
42
  ```
43
+
19
44
  #### Examples:
20
45
  ```ruby
21
46
  User.friends.random # return ActiveRecord::Relation with user`s random friends
22
47
  User.find_random.friends.random # return ActiveRecord::Relation with random user`s random friends
23
48
  Post.published.random.limit(3) # return ActiveRecord::Relation with 3 published posts
24
49
  Post.published.find_many_random(3) # --//--
50
+ Post.published.fast_random(3) # --//-- and faster
25
51
  ```
26
52
 
27
-
28
53
  ## Installation
29
54
  Add this line to your application's Gemfile:
30
55
 
@@ -42,8 +67,16 @@ Or install it yourself as:
42
67
  $ gem install random_order
43
68
  ```
44
69
 
70
+ # TODO
71
+ - `oracle` adapter
72
+ - `sqlserver` adapter
73
+ - `MongoDB` with `Mongoid`
74
+
45
75
  ## Contributing
46
76
  Contribution directions go here.
47
77
 
78
+ ### Source
79
+ `https://rubygems.org/gems/random_order`
80
+
48
81
  ## License
49
82
  The gem is available as open-source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -4,7 +4,7 @@ module RandomOrder
4
4
  class Railtie < ::Rails::Railtie
5
5
  include Extension
6
6
 
7
- initializer 'RandomOrder.initialize' do
7
+ config.before_initialize do
8
8
  if RandomOrder.const_defined?("ActiveRecord")
9
9
  ActiveRecord::Base.send :extend, Extension
10
10
  end
@@ -9,13 +9,14 @@ module RandomOrder
9
9
  end
10
10
 
11
11
  def random
12
- case RandomOrder.adapter
13
- when 'mysql2'
14
- self.order(Arel.sql('RAND()'))
15
- when 'postgresql'
16
- self.order(Arel.sql('RANDOM()'))
17
- when 'sqlite3'
18
- self.order(Arel.sql('RANDOM()'))
12
+ self.order(RandomOrder.order_func)
13
+ end
14
+
15
+ def fast_random(n = 1)
16
+ if self.primary_key.present?
17
+ RandomOrder.sql_query_string(self, n)
18
+ else
19
+ random.limit(n)
19
20
  end
20
21
  end
21
22
  end
@@ -1,3 +1,3 @@
1
1
  module RandomOrder
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'
3
3
  end
data/lib/random_order.rb CHANGED
@@ -1,13 +1,25 @@
1
1
  require "random_order/railtie"
2
2
 
3
3
  module RandomOrder
4
+ ORDERS = Hash.new(Arel.sql('RANDOM()')).update({"mysql2" => Arel.sql('RAND()')})
5
+
4
6
  def self.adapter
5
- @@adapter ||= detect_adapter
7
+ @@adapter ||= begin
8
+ if self.const_defined?("ActiveRecord")
9
+ ActiveRecord::Base.configurations[Rails.env]['adapter']
10
+ end
11
+ end
6
12
  end
7
13
 
8
- def self.detect_adapter
9
- if self.const_defined?("ActiveRecord")
10
- ActiveRecord::Base.configurations[Rails.env]['adapter']
11
- end
14
+ def RandomOrder.order_func
15
+ ORDERS[adapter]
16
+ end
17
+
18
+ def self.sql_query_string(model, n)
19
+ model.from(
20
+ "(SELECT * FROM #{model.table_name}, ( SELECT #{model.primary_key} AS sid "\
21
+ "FROM #{model.table_name} ORDER BY #{RandomOrder.order_func} LIMIT #{n} ) tmp WHERE "\
22
+ "#{model.table_name}.#{model.primary_key} = tmp.sid) as #{model.table_name}"
23
+ )
12
24
  end
13
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: random_order
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vitalii Kasianchuk
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-20 00:00:00.000000000 Z
11
+ date: 2020-02-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -66,7 +66,8 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- description: Find random record in your models, just to DRY your code.
69
+ description: With this gem you can return a random record from database using SQL
70
+ or using `randomscope` to return records in random order
70
71
  email:
71
72
  - kasvit93@gmail.com
72
73
  executables: []
@@ -103,5 +104,6 @@ requirements: []
103
104
  rubygems_version: 3.0.3
104
105
  signing_key:
105
106
  specification_version: 4
106
- summary: Find random record in your models, just to DRY your code.
107
+ summary: This gem is adding three methods to ActiveRecord Relations - `random` , `find_random`
108
+ and `find_many_random(...)`.
107
109
  test_files: []