occams-record 1.4.0 → 1.5.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: c1dc718c0f99f5ad039974f8db3bd1c5304e41a3b3275d26dd1d86235c7790fe
4
- data.tar.gz: 8af374148ca1f1c8342b7eb8fdb30031d6c31a1d923a6e7cab55b96712ed2602
3
+ metadata.gz: d09d84ccc4713f32959380098b74112e45fa6a84a47698f1cec2d6fc4c4886a9
4
+ data.tar.gz: b94244c91ed19b02cfb36ff02c72b6510ab38da73f7d76e13e8104713fa2ed03
5
5
  SHA512:
6
- metadata.gz: 54b539bc70b1fc92c087fbc91f7edbaa1eb4dabacfda80ca0afa4ccd4ac53e832d431f3c95e35785cfa7bd7075879c655ae54019c3f341255b4411929b5ae615
7
- data.tar.gz: c1c9aed1007bcfeb0e577d08af6f86fa340e375fede08af03bd18fbc2538cfcbd4838fc5bd07c672fca6e02ca3c0ec9e8d442b3e3275deff58215dfba873df7a
6
+ metadata.gz: 950a0baa705302727a9ab9d20bb286e2fdc44cdd8b6aee3edb1b02c0a640786beca3492e799bcf4efe87c3a01289c6f4edb2daa07dc24650a5c29d6276733737
7
+ data.tar.gz: dc07af2830bf268dac941834d36bc1cca3ffe64f5e1e3eadfe901b11fe1fcf545ba9804da4fd683697ee26201faf0936b06aaa203ac661aa14eed69b036e2109
data/README.md CHANGED
@@ -9,7 +9,7 @@ OccamsRecord is a high-efficiency, advanced query library for use alongside Acti
9
9
  * 3x-5x faster than ActiveRecord queries, *minimum*.
10
10
  * Uses 1/3 the memory of ActiveRecord query results.
11
11
  * Eliminates the N+1 query problem. (This often exceeds the baseline 3x-5x gain.)
12
- * Support for cursors (Postgres only, new in v1.4.0-beta1)
12
+ * Support for cursors (Postgres only, new in v1.4.0)
13
13
 
14
14
  ### 2) Supercharged querying & eager loading
15
15
 
@@ -20,7 +20,9 @@ Continue using ActiveRecord's query builder, but let Occams take over running th
20
20
  ```ruby
21
21
  OccamsRecord
22
22
  .query(User.active)
23
- .eager_load(:orders, ->(q) { q.where("created_at >= ?", date).order("created_at DESC") })
23
+ .eager_load(:orders) {
24
+ scope { |q| q.where("created_at >= ?", date).order("created_at DESC") }
25
+ }
24
26
  ```
25
27
 
26
28
  **Use `ORDER BY` with `find_each`/`find_in_batches`**
@@ -158,9 +160,12 @@ orders = OccamsRecord
158
160
  .query(q)
159
161
  # Only SELECT the columns you need. Your DBA will thank you.
160
162
  .eager_load(:customer, select: "id, name")
161
-
162
- # A Proc can use ActiveRecord's query builder
163
- .eager_load(:line_items, ->(q) { q.active.order("created_at") }) {
163
+
164
+ # Or use 'scope' to access the full power of ActiveRecord's query builder.
165
+ # Here, only 'active' line items will be returned, and in a specific order.
166
+ .eager_load(:line_items) {
167
+ scope { |q| q.active.order("created_at") }
168
+
164
169
  eager_load(:product)
165
170
  eager_load(:something_else)
166
171
  }
@@ -354,7 +359,7 @@ bundle install
354
359
  bundle exec rake test
355
360
 
356
361
  # test against Postgres
357
- TEST_DATABASE_URL=postgres://postgres@localhost:5432/occams_record bundle exec rake test
362
+ TEST_DATABASE_URL=postgresql://postgres@localhost:5432/occams_record bundle exec rake test
358
363
 
359
364
  # test against MySQL
360
365
  TEST_DATABASE_URL=mysql2://root:@127.0.0.1:3306/occams_record bundle exec rake test
@@ -19,7 +19,7 @@ module OccamsRecord
19
19
  # @yield perform eager loading on *this* association (optional)
20
20
  #
21
21
  def initialize(ref, scope = nil, use: nil, as: nil, optimizer: :select, &builder)
22
- @ref, @scope, @use, @as = ref, scope, use, as
22
+ @ref, @scopes, @use, @as = ref, Array(scope), use, as
23
23
  @model = ref.klass
24
24
  @name = (as || ref.name).to_s
25
25
  @eager_loaders = EagerLoaders::Context.new(@model)
@@ -27,6 +27,20 @@ module OccamsRecord
27
27
  instance_exec(&builder) if builder
28
28
  end
29
29
 
30
+ #
31
+ # An alternative to passing a "scope" lambda to the constructor. Your block is passed the query
32
+ # so you can call select, where, order, etc on it.
33
+ #
34
+ # If you call scope multiple times, the results will be additive.
35
+ #
36
+ # @yield [ActiveRecord::Relation] a relation to modify with select, where, order, etc
37
+ # @return self
38
+ #
39
+ def scope(&scope)
40
+ @scopes << scope if scope
41
+ self
42
+ end
43
+
30
44
  #
31
45
  # Run the query and merge the results into the given rows.
32
46
  #
@@ -71,7 +85,7 @@ module OccamsRecord
71
85
  def base_scope
72
86
  q = @ref.klass.all
73
87
  q = q.instance_exec(&@ref.scope) if @ref.scope
74
- q = @scope.(q) if @scope
88
+ q = @scopes.reduce(q) { |acc, scope| scope.(acc) }
75
89
  q
76
90
  end
77
91
  end
@@ -115,7 +115,7 @@ module OccamsRecord
115
115
 
116
116
  def build_loader!(assoc, custom_name, scope, select, use, optimizer, builder)
117
117
  build_loader(assoc, custom_name, scope, select, use, optimizer, builder) ||
118
- raise("OccamsRecord: No assocation `:#{assoc}` on `#{@model.name}` or subclasses")
118
+ raise("OccamsRecord: No association `:#{assoc}` on `#{@model.name}` or subclasses")
119
119
  end
120
120
 
121
121
  def build_loader(assoc, custom_name, scope, select, use, optimizer, builder)
@@ -17,7 +17,7 @@ module OccamsRecord
17
17
  # @yield perform eager loading on *this* association (optional)
18
18
  #
19
19
  def initialize(ref, scope = nil, use: nil, as: nil, optimizer: nil, &builder)
20
- @ref, @scope, @use = ref, scope, use
20
+ @ref, @scopes, @use = ref, Array(scope), use
21
21
  @name = (as || ref.name).to_s
22
22
  @foreign_type = @ref.foreign_type.to_sym
23
23
  @foreign_key = @ref.foreign_key.to_sym
@@ -25,6 +25,20 @@ module OccamsRecord
25
25
  instance_exec(&builder) if builder
26
26
  end
27
27
 
28
+ #
29
+ # An alternative to passing a "scope" lambda to the constructor. Your block is passed the query
30
+ # so you can call select, where, order, etc on it.
31
+ #
32
+ # If you call scope multiple times, the results will be additive.
33
+ #
34
+ # @yield [ActiveRecord::Relation] a relation to modify with select, where, order, etc
35
+ # @return self
36
+ #
37
+ def scope(&scope)
38
+ @scopes << scope if scope
39
+ self
40
+ end
41
+
28
42
  #
29
43
  # Run the query and merge the results into the given rows.
30
44
  #
@@ -83,7 +97,7 @@ module OccamsRecord
83
97
  def base_scope(model)
84
98
  q = model.all
85
99
  q = q.instance_exec(&@ref.scope) if @ref.scope
86
- q = @scope.(q) if @scope
100
+ q = @scopes.reduce(q) { |acc, scope| scope.(acc) }
87
101
  q
88
102
  end
89
103
  end
@@ -3,5 +3,5 @@
3
3
  #
4
4
  module OccamsRecord
5
5
  # @private
6
- VERSION = "1.4.0".freeze
6
+ VERSION = "1.5.0".freeze
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: occams-record
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Hollinger
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-25 00:00:00.000000000 Z
11
+ date: 2023-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -83,7 +83,7 @@ homepage: https://jhollinger.github.io/occams-record/
83
83
  licenses:
84
84
  - MIT
85
85
  metadata: {}
86
- post_install_message:
86
+ post_install_message:
87
87
  rdoc_options: []
88
88
  require_paths:
89
89
  - lib
@@ -98,8 +98,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
98
  - !ruby/object:Gem::Version
99
99
  version: '0'
100
100
  requirements: []
101
- rubygems_version: 3.0.3.1
102
- signing_key:
101
+ rubygems_version: 3.4.1
102
+ signing_key:
103
103
  specification_version: 4
104
104
  summary: The missing high-efficiency query API for ActiveRecord
105
105
  test_files: []