random_order 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []