queryable 2.1.1 → 3.0.2

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
  SHA1:
3
- metadata.gz: 47991b347fa04e683c64a77a520c71e01891b471
4
- data.tar.gz: 5cd9cece435510a6c432fc82230333c62d7f3b36
3
+ metadata.gz: c03af4447c57550543e85fbf72d5d6a8611b6480
4
+ data.tar.gz: 91599f3cac8467d3916886075567896a52082ccc
5
5
  SHA512:
6
- metadata.gz: a647c943402b09005f4d58b14013f7e366eea865e6e86b2050bc04a5b7f26dd552874e1e2ea27ff6e22f9f0ded5d2f58a070f2e089f5abff396e27fdd9a4d233
7
- data.tar.gz: d47b1fc13ac6a04a158f91714d85d5e6674b6e29b827d87f5a75b461c32a171086ce7d52d5c9c4a92160596038c5b4e1303edad562261e87e69252602fcb4d26
6
+ metadata.gz: 021e3386328437dc3bf6eb22f060cfa5f05bb1d8652436a44f9fb6e457ad1f27f88e1961c132cecbc91f2f7af5be4c280755f1757d51846d4f0faeb274a68b65
7
+ data.tar.gz: d2471a7f808b810a0a82cd7370e645a2de2b738f13f11f4cd8b8f17d4ab7e9065101ed1023740cc22228a6f7268e3811f040c097ec93f1917bdac9fbe4dcbf65
data/README.md CHANGED
@@ -44,8 +44,26 @@ CustomerQuery.new(shop.customers).miller_fans
44
44
  By default most Array methods are delegated to the internal query. It's possible
45
45
  to delegate extra methods to the query by calling `delegate`.
46
46
  ```ruby
47
- def CustomersQuery
48
- delegate :update_all, :destroy_all
47
+ class CustomersQuery
48
+ include Queryable
49
+
50
+ delegate :update_all, :destroy_all, :exists?
51
+ end
52
+ ```
53
+
54
+ ### Delegate and Chain
55
+
56
+ Sometimes you want to delegate a method to the internal query, but continue
57
+ working with the query object like if you were calling scopes.
58
+
59
+ You can achieve that using `delegate_and_chain`, which will delegate the method
60
+ call, assign the return value as the internal query, and return the query object.
61
+
62
+ ```ruby
63
+ class CustomersQuery
64
+ include Queryable
65
+
66
+ delegate_and_chain :where, :order_by
49
67
  end
50
68
  ```
51
69
 
@@ -55,7 +73,24 @@ end
55
73
  * You can inherit, mixin, and chain queries in a very natural way.
56
74
  * Increased testability, pretty close to being ORM/ODM agnostic.
57
75
 
58
- ## Optional Modules
76
+ ## Basic Usage
77
+
78
+ If you are using Mongoid or ActiveRecord, you might want to try the
79
+ `Queryable::Mongoid` and `Queryable::ActiveRecord` modules that already take
80
+ care of delegating and chaining most of the methods in the underlying queries.
81
+
82
+ ```ruby
83
+ class CustomersQuery
84
+ include Queryable::Mongoid
85
+ end
86
+
87
+ CustomersQuery.new.where(:amount_purchased.gt => 2).active.asc(:logged_in_at)
88
+ ```
89
+
90
+ This modules also include all the optional modules. If you would like to opt-out
91
+ of the other modules you can follow the approach in the [Notes](https://github.com/ElMassimo/queryable#notes) section.
92
+
93
+ ## Advanced Usage
59
94
  There are three opt-in modules that can help you when creating query objects.
60
95
  These modules would need to be manually required during app initialization or
61
96
  wherever necessary (in Rails, config/initializers).
data/lib/queryable.rb CHANGED
@@ -38,8 +38,21 @@ module Queryable
38
38
 
39
39
  # Public: Delegates the specified methods to the internal query.
40
40
  def delegate(*methods)
41
- to = methods.last.is_a?(Hash) && methods.pop[:to] || :queryable
42
- def_delegators(to == :class ? 'self.class' : to, *methods)
41
+ def_delegators extract_delegation_target(methods), *methods
42
+ end
43
+
44
+ # Public: Delegates the specified methods to the internal query, assigns the
45
+ # return value, and returns self.
46
+ def delegate_and_chain(*methods)
47
+ to = extract_delegation_target(methods)
48
+ class_eval methods.map { |name| Queryable.chained_method(name, to) }.join
49
+ end
50
+
51
+ # Internal: Extracts the :to option of the arguments, uses the internal
52
+ # query object as the target if no option is provided.
53
+ def extract_delegation_target(args)
54
+ to = args.last.is_a?(Hash) && args.pop[:to] || :queryable
55
+ to == :class ? 'self.class' : to
43
56
  end
44
57
 
45
58
  # Public: Defines a new method that executes the passed proc or block in
@@ -74,12 +87,23 @@ module Queryable
74
87
  end
75
88
  end
76
89
 
90
+ # Internal: Generates a method that delegates the call to the an internal
91
+ # object, assigns the return value, and returns self.
92
+ #
93
+ # Returns a String with the code of the method.
94
+ def self.chained_method(name, accessor)
95
+ <<-CHAIN
96
+ def #{name}(*args, &block)
97
+ @queryable = #{accessor}.__send__(:#{name}, *args, &block)
98
+ self
99
+ end
100
+ CHAIN
101
+ end
102
+
77
103
  # Internal: Default methods to be delegated to the internal query.
78
104
  #
79
105
  # Returns an Array with the name of the methods to delegate.
80
106
  def self.default_delegated_methods
81
- Array.instance_methods - Object.instance_methods +
82
- [:all, :where, :distinct, :group, :having, :includes, :joins, :limit, :offset, :order, :reverse_order] +
83
- [:==, :as_json, :cache_key, :decorate]
107
+ Array.instance_methods - Object.instance_methods + [:all, :==, :as_json, :decorate]
84
108
  end
85
109
  end
@@ -0,0 +1,30 @@
1
+ require 'queryable/chainable'
2
+ require 'queryable/default_query'
3
+ require 'queryable/default_scope'
4
+
5
+ # Public: Provides default configuration for query objects that decorate a
6
+ # ActiveRecord::Relation object, delegating the most used methods.
7
+ module Queryable
8
+ module ActiveRecord
9
+
10
+ DELEGATED_METHODS = [
11
+ :average, :maximum, :minimum, :sum, :exists?, :find_by, :build, :create,
12
+ :pluck, :entries, :new, :explain
13
+ ]
14
+
15
+ CHAINABLE_METHODS = [
16
+ :where, :bind, :create_with, :distinct, :eager_load, :extending, :from,
17
+ :group, :having, :includes, :joins, :limit, :lock, :none, :offset, :order,
18
+ :preload, :readonly, :references, :reorder, :reverse_order, :select,
19
+ :uniq, :not, :unscoped, :unscope, :only
20
+ ]
21
+
22
+ # Internal: Adds class methods, and default initialization.
23
+ def self.included(base)
24
+ base.send(:include, Chainable, DefaultQuery, DefaultScope, ::Queryable)
25
+
26
+ base.delegate *DELEGATED_METHODS
27
+ base.delegate_and_chain *CHAINABLE_METHODS
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ require 'queryable/chainable'
2
+ require 'queryable/default_query'
3
+ require 'queryable/default_scope'
4
+
5
+ # Public: Provides default configuration for query objects that decorate a
6
+ # Mongoid::Criteria object, delegating the most used methods in Criteria.
7
+ module Queryable
8
+ module Mongoid
9
+
10
+ DELEGATED_METHODS = [
11
+ :avg, :max, :min, :sum, :exists?, :set, :pull, :push, :add_to_set,
12
+ :find_by, :build, :create, :destroy, :destroy_all, :update, :update_all,
13
+ :delete, :pluck, :distinct, :selector, :rename, :entries, :new, :explain
14
+ ]
15
+
16
+ CHAINABLE_METHODS = [
17
+ :where, :ne, :nin, :gt, :gte, :in, :lt, :lte, :between, :and, :or, :not,
18
+ :intersect, :override, :union, :exists, :elem_match, :with_size,
19
+ :none, :unscoped, :includes, :order_by, :asc, :desc, :skip, :limit
20
+ ]
21
+
22
+ # Internal: Adds class methods, and default initialization.
23
+ def self.included(base)
24
+ base.send(:include, Chainable, DefaultQuery, DefaultScope, ::Queryable)
25
+
26
+ base.delegate *DELEGATED_METHODS
27
+ base.delegate_and_chain *CHAINABLE_METHODS
28
+ end
29
+ end
30
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: queryable
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 3.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Máximo Mussini
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-03 00:00:00.000000000 Z
11
+ date: 2014-11-14 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Queryable is a module that encapsulates query building so you don't have
14
14
  to tuck scopes inside your models.
@@ -21,9 +21,11 @@ extra_rdoc_files:
21
21
  files:
22
22
  - README.md
23
23
  - lib/queryable.rb
24
+ - lib/queryable/active_record.rb
24
25
  - lib/queryable/chainable.rb
25
26
  - lib/queryable/default_query.rb
26
27
  - lib/queryable/default_scope.rb
28
+ - lib/queryable/mongoid.rb
27
29
  homepage: https://github.com/ElMassimo/queryable
28
30
  licenses:
29
31
  - MIT