occams-record 0.1.0 → 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
  SHA1:
3
- metadata.gz: dd652d5b028ca9870438dd907b3d5fba86eec92f
4
- data.tar.gz: bb9033890d9f488deeb6d077b35d76b17b78fc4e
3
+ metadata.gz: 9637536cde1b2f57e976fa87ab6dfc2bdb34dee0
4
+ data.tar.gz: b639ad58c3b7b328a7e37a858b5693832604e620
5
5
  SHA512:
6
- metadata.gz: ebf6b5a27af8b77beab59ef971b2b53f5909bd586f461fb05c240e384f13705016fe5a71a5e5a772d7511ea8c10042a874cf284a7074eb00b35f277c15fc509d
7
- data.tar.gz: b822de2b3cc6c0402e7ffc3b35c2424851d2b4c44e1316f05924c8a7489b2fb7a4cd2b20c7f0a4ba4c0e89806a0204ae155c1ce04d66352114cd1e24b7d37f7e
6
+ metadata.gz: c84146477d0ba45f0f5a36386e06ade453339b45473a8bebba2f4b4da2eda876e6cfe62dc86c4a1f539838ff765c3753436f10853bc97df2a800f605c064daba
7
+ data.tar.gz: f941ae734b28a694921090d664e3a263c168aba74461d3106c3a04aeeaba3889157db5629c89f3f57187150e6622b3bb66977371999525c89188022da1db2a5b
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Occam's Record
1
+ # Occam's Record [![Build Status](https://travis-ci.org/jhollinger/occams-record.svg?branch=master)](https://travis-ci.org/jhollinger/occams-record)
2
2
 
3
3
  > Do not multiply entities beyond necessity. -- Occam's Razor
4
4
 
@@ -11,7 +11,7 @@ For those stuck with ActiveRecord, OccamsRecord seeks to solve these issues by m
11
11
 
12
12
  **What does this buy you?**
13
13
 
14
- * OccamsRecord results are **one-thid the size** of ActiveRecord results.
14
+ * OccamsRecord results are **one-third the size** of ActiveRecord results.
15
15
  * OccamsRecord queries run **three times faster** than ActiveRecord queries, or more.
16
16
  * When you're eager loading associations you may specify which columns to `SELECT`. (This can be a significant performance boost to both your database and Rails app, on top of the above numbers.)
17
17
 
@@ -25,107 +25,125 @@ For those stuck with ActiveRecord, OccamsRecord seeks to solve these issues by m
25
25
 
26
26
  Glad you asked. [Look over the results yourself.](https://github.com/jhollinger/occams-record/wiki/Measurements)
27
27
 
28
- ## Examples
28
+ ## Usage
29
+
30
+ **Add to your Gemfile**
31
+
32
+ ```ruby
33
+ gem 'occams-record'
34
+ ```
29
35
 
30
36
  **Simple example**
31
37
 
32
- widgets = OccamsRecord.
33
- query(Widget.order("name")).
34
- eager_load(:category).
35
- run
38
+ ```ruby
39
+ widgets = OccamsRecord.
40
+ query(Widget.order("name")).
41
+ eager_load(:category).
42
+ run
36
43
 
37
- widgets[0].id
38
- => 1000
44
+ widgets[0].id
45
+ => 1000
39
46
 
40
- widgets[0].name
41
- => "Widget 1000"
47
+ widgets[0].name
48
+ => "Widget 1000"
42
49
 
43
- widgets[0].category.name
44
- => "Category 1"
50
+ widgets[0].category.name
51
+ => "Category 1"
52
+ ```
45
53
 
46
54
  **More complicated example**
47
55
 
48
56
  Notice that we're eager loading splines, but *only the fields that we need*. If that's a wide table, your DBA will thank you.
49
57
 
50
- widgets = OccamsRecord.
51
- query(Widget.order("name")).
52
- eager_load(:category).
53
- eager_load(:splines, -> { select("widget_id, description") }).
54
- run
58
+ ```ruby
59
+ widgets = OccamsRecord.
60
+ query(Widget.order("name")).
61
+ eager_load(:category).
62
+ eager_load(:splines, -> { select("widget_id, description") }).
63
+ run
55
64
 
56
- widgets[0].splines.map { |s| s.description }
57
- => ["Spline 1", "Spline 2", "Spline 3"]
65
+ widgets[0].splines.map { |s| s.description }
66
+ => ["Spline 1", "Spline 2", "Spline 3"]
58
67
 
59
- widgets[1].splines.map { |s| s.description }
60
- => ["Spline 4", "Spline 5"]
68
+ widgets[1].splines.map { |s| s.description }
69
+ => ["Spline 4", "Spline 5"]
70
+ ```
61
71
 
62
72
  **An insane example, but only half as insane as the one that prompted the creation of this library**
63
73
 
64
74
  In addition to custom eager loading queries, we're also adding nested eager loading (and customizing those queries!).
65
75
 
66
- widgets = OccamsRecord.
67
- query(Widget.order("name")).
68
- eager_load(:category).
76
+ ```ruby
77
+ widgets = OccamsRecord.
78
+ query(Widget.order("name")).
79
+ eager_load(:category).
69
80
 
70
- # load order_items, but only the fields needed to identify which orders go with which widgets
71
- eager_load(:order_items, -> { select("widget_id, order_id") }) {
81
+ # load order_items, but only the fields needed to identify which orders go with which widgets
82
+ eager_load(:order_items, -> { select("widget_id, order_id") }) {
72
83
 
73
- # load the orders
74
- eager_load(:orders) {
84
+ # load the orders
85
+ eager_load(:orders) {
75
86
 
76
- # load the customers who made the orders, but only their names
77
- eager_load(:customer, -> { select("id, name") })
78
- }
79
- }.
80
- run
87
+ # load the customers who made the orders, but only their names
88
+ eager_load(:customer, -> { select("id, name") })
89
+ }
90
+ }.
91
+ run
92
+ ```
81
93
 
82
94
  ## Injecting instance methods
83
95
 
84
96
  By default your results will only have getters for selected columns and eager-loaded associations. If you must, you *can* inject extra methods into your results by putting those methods into a Module. NOTE this is discouraged, as you should try to maintain a clear separation between your persistence layer and your domain.
85
97
 
86
- module MyWidgetMethods
87
- def to_s
88
- name
89
- end
98
+ ```ruby
99
+ module MyWidgetMethods
100
+ def to_s
101
+ name
102
+ end
90
103
 
91
- def expensive?
92
- price_per_unit > 100
93
- end
94
- end
104
+ def expensive?
105
+ price_per_unit > 100
106
+ end
107
+ end
95
108
 
96
- module MyOrderMethods
97
- def description
98
- "#{order_number} - #{date}"
99
- end
100
- end
109
+ module MyOrderMethods
110
+ def description
111
+ "#{order_number} - #{date}"
112
+ end
113
+ end
101
114
 
102
- widgets = OccamsRecord.
103
- query(Widget.order("name"), use: MyWidgetMethods).
104
- eager_load(:orders, use: MyOrderMethods).
105
- run
115
+ widgets = OccamsRecord.
116
+ query(Widget.order("name"), use: MyWidgetMethods).
117
+ eager_load(:orders, use: MyOrderMethods).
118
+ run
106
119
 
107
- widgets[0].to_s
108
- => "Widget A"
120
+ widgets[0].to_s
121
+ => "Widget A"
109
122
 
110
- widgets[0].price_per_unit
111
- => 57.23
123
+ widgets[0].price_per_unit
124
+ => 57.23
112
125
 
113
- widgets[0].expensive?
114
- => false
126
+ widgets[0].expensive?
127
+ => false
115
128
 
116
- widgets[0].orders[0].description
117
- => "O839SJZ98B 1/8/2017"
129
+ widgets[0].orders[0].description
130
+ => "O839SJZ98B 1/8/2017"
131
+ ```
118
132
 
119
133
  ## Testing
120
134
 
121
135
  To run the tests, simply run:
122
136
 
123
- bundle install
124
- bundle exec rake test
137
+ ```bash
138
+ bundle install
139
+ bundle exec rake test
140
+ ```
125
141
 
126
142
  By default, bundler will install the latest (supported) version of ActiveRecord. To specify a version to test against, run:
127
143
 
128
- AR=4.2 bundle update activerecord
129
- bundle exec rake test
144
+ ```bash
145
+ AR=4.2 bundle update activerecord
146
+ bundle exec rake test
147
+ ```
130
148
 
131
149
  Look inside `Gemfile` to see all testable versions.
@@ -6,7 +6,7 @@ module OccamsRecord
6
6
  class Base
7
7
  # @return [String] association name
8
8
  attr_reader :name
9
- # @return [Module] optional Module to include in the result class
9
+ # @return [Array<Module>] optional Module to include in the result class (single or array)
10
10
  attr_reader :use
11
11
  # @return [Proc] optional Proc for eager loading things on this association
12
12
  attr_reader :eval_block
@@ -14,7 +14,7 @@ module OccamsRecord
14
14
  #
15
15
  # @param ref [ActiveRecord::Association] the ActiveRecord association
16
16
  # @param scope [Proc] a scope to apply to the query (optional)
17
- # @param use [Module] optional Module to include in the result class
17
+ # @param use [Array(Module)] optional Module to include in the result class (single or array)
18
18
  # @param eval_block [Proc] a block where you may perform eager loading on *this* association (optional)
19
19
  #
20
20
  def initialize(ref, scope = nil, use = nil, &eval_block)
@@ -4,7 +4,7 @@ module OccamsRecord
4
4
  class PolymorphicBelongsTo
5
5
  # @return [String] association name
6
6
  attr_reader :name
7
- # @return [Module] optional Module to include in the result class
7
+ # @return [Array<Module>] optional Module to include in the result class (single or array)
8
8
  attr_reader :use
9
9
  # @return [Proc] optional Proc for eager loading things on this association
10
10
  attr_reader :eval_block
@@ -12,7 +12,7 @@ module OccamsRecord
12
12
  #
13
13
  # @param ref [ActiveRecord::Association] the ActiveRecord association
14
14
  # @param scope [Proc] a scope to apply to the query (optional)
15
- # @param use [Module] optional Module to include in the result class
15
+ # @param use [Array<Module>] optional Module to include in the result class (single or array)
16
16
  # @param eval_block [Proc] a block where you may perform eager loading on *this* association (optional)
17
17
  #
18
18
  def initialize(ref, scope = nil, use = nil, &eval_block)
@@ -44,7 +44,7 @@ module OccamsRecord
44
44
  # Initialize a new query.
45
45
  #
46
46
  # @param scope [ActiveRecord::Relation]
47
- # @param use [Module] optional Module to include in the result class
47
+ # @param use [Array<Module>] optional Module to include in the result class (single or array)
48
48
  # @param query_logger [Array] (optional) an array into which all queries will be inserted for logging/debug purposes
49
49
  # @param eager_loaders [OccamsRecord::EagerLoaders::Base]
50
50
  # @param eval_block [Proc] block that will be eval'd on this instance. Can be used for eager loading. (optional)
@@ -66,8 +66,9 @@ module OccamsRecord
66
66
  #
67
67
  # @param assoc [Symbol] name of association
68
68
  # @param scope [Proc] a scope to apply to the query (optional)
69
- # @param use [Module] optional Module to include in the result class
69
+ # @param use [Array<Module>] optional Module to include in the result class (single or array)
70
70
  # @param eval_block [Proc] a block where you may perform eager loading on *this* association (optional)
71
+ # @return [OccamsRecord::Query] returns self
71
72
  #
72
73
  def eager_load(assoc, scope = nil, use: nil, &eval_block)
73
74
  ref = model.reflections[assoc.to_s]
@@ -12,12 +12,12 @@ module OccamsRecord
12
12
  # @param model [ActiveRecord::Base] the AR model representing the table (it holds column & type info).
13
13
  # @param column_names [Array<String>] the column names in the result set. The order MUST match the order returned by the query.
14
14
  # @param association_names [Array<String>] names of associations that will be eager loaded into the results.
15
- # @param included_module [Module] (optional)
15
+ # @param included_modules [Array<Module>] (optional)
16
16
  # @return [OccamsRecord::ResultRow] a class customized for this result set
17
17
  #
18
- def self.build_result_row_class(model, column_names, association_names, included_module = nil)
18
+ def self.build_result_row_class(model, column_names, association_names, included_modules = nil)
19
19
  Class.new(ResultRow) do
20
- include included_module if included_module
20
+ Array(included_modules).each { |mod| include mod } if included_modules
21
21
 
22
22
  self.columns = column_names.map(&:to_s)
23
23
  self.associations = association_names.map(&:to_s)
@@ -3,5 +3,5 @@
3
3
  #
4
4
  module OccamsRecord
5
5
  # Library version
6
- VERSION = '0.1.0'.freeze
6
+ VERSION = '0.2.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: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Hollinger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-19 00:00:00.000000000 Z
11
+ date: 2017-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord