queryable 1.0.1 → 2.0.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 +4 -4
- data/README.md +1 -0
- data/lib/queryable.rb +57 -52
- data/lib/queryable/default_query.rb +40 -0
- data/lib/queryable/default_scope.rb +53 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 28570cfafe1680583b92ea618a85cbca197f5c4b
|
4
|
+
data.tar.gz: 981e0042933205c1bf4c10daa8db4dcecec540f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ecfd3bb32c31a300bd768cbf82d5f42628e1012259de2df4c174d68ad2ba368d2db4a0666dfb482ff7a94391dedbef9c6e658c3fba19a62c14ee2ff9fd2119ae
|
7
|
+
data.tar.gz: 318dea62093ecd3e8defe4e3b87bbf0b0a5169980164d5597e1ed51bfe06193a731d577bcf05a029b96fecd3939c518ac910e970e0606258ea44c31627831d91
|
data/README.md
CHANGED
@@ -3,6 +3,7 @@ Queryable
|
|
3
3
|
[](http://badge.fury.io/rb/queryable)
|
4
4
|
[](https://travis-ci.org/ElMassimo/queryable)
|
5
5
|
[](https://coveralls.io/r/ElMassimo/queryable)
|
6
|
+
[](http://inch-ci.org/github/ElMassimo/queryable)
|
6
7
|
<!-- [](https://codeclimate.com/github/ElMassimo/queryable) -->
|
7
8
|
|
8
9
|
Queryable is a mixin that allows you to easily define query objects with chainable scopes.
|
data/lib/queryable.rb
CHANGED
@@ -9,19 +9,19 @@
|
|
9
9
|
# include Queryable
|
10
10
|
# scope(:too_damn_high) { where(:level.gt => 9000) }
|
11
11
|
# end
|
12
|
-
#
|
12
|
+
#'
|
13
13
|
module Queryable
|
14
14
|
|
15
15
|
# Internal: Adds class methods, a query accessor, and method delegation.
|
16
16
|
def self.included(base)
|
17
|
-
base.extend ClassMethods
|
18
17
|
base.extend Forwardable
|
18
|
+
base.extend ClassMethods
|
19
19
|
base.class_eval do
|
20
|
-
|
21
20
|
# Public: Gets/Sets the internal query.
|
22
21
|
attr_accessor :query
|
23
22
|
|
24
|
-
|
23
|
+
# Internal: Delegates Array and Criteria methods to the internal query.
|
24
|
+
delegate *Queryable.default_delegated_methods
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -32,47 +32,15 @@ module Queryable
|
|
32
32
|
@query = query.all
|
33
33
|
end
|
34
34
|
|
35
|
-
# Public: Convenience setter for the internal query that returns self. The
|
36
|
-
# query is set to the value returned by the block. Useful when you need to
|
37
|
-
# access the context of the Queryable in addition to the query.
|
38
|
-
#
|
39
|
-
# block - A block that returns the new value of the internal query.
|
40
|
-
#
|
41
|
-
# Yields the internal query, which can be used to build upon.
|
42
|
-
# def search(query)
|
43
|
-
#
|
44
|
-
# Examples
|
45
|
-
#
|
46
|
-
# # Accessing a constant in the Queryable object context.
|
47
|
-
# LATEST_COUNT = 10
|
48
|
-
# def latest
|
49
|
-
# define_query {|query| query.limit(LATEST_COUNT) }
|
50
|
-
# end
|
51
|
-
#
|
52
|
-
# # We use it because the last method we chain does not return self.
|
53
|
-
# def recent_by_name
|
54
|
-
# define_query { recent.order(:name) }
|
55
|
-
# end
|
56
|
-
#
|
57
|
-
# # Extracted from a scope for clarity.
|
58
|
-
# def search(field_values)
|
59
|
-
# define_query do |users|
|
60
|
-
# field_values.inject(users) { |users, (field, value)|
|
61
|
-
# users.where(field => /#{value}/i)
|
62
|
-
# }
|
63
|
-
# end
|
64
|
-
# end
|
65
|
-
#
|
66
|
-
# Returns the Queryable object itself (self).
|
67
|
-
def define_query
|
68
|
-
@query = yield(query)
|
69
|
-
self
|
70
|
-
end
|
71
|
-
|
72
35
|
# Internal: Contains the Queryable class methods.
|
73
36
|
module ClassMethods
|
74
|
-
|
75
|
-
# the
|
37
|
+
|
38
|
+
# Public: Delegates the specified methods to the internal query.
|
39
|
+
def delegate(*methods)
|
40
|
+
methods.last.is_a?(Hash) ? super : def_delegators(:query, *methods)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Public: Defines a new scope method, or makes an existing method chainable.
|
76
44
|
#
|
77
45
|
# name - Name of the scope to define for this Queryable.
|
78
46
|
#
|
@@ -94,22 +62,59 @@ module Queryable
|
|
94
62
|
# where(_type: "#{brand}ExtremelyFastRacingCar")
|
95
63
|
# end
|
96
64
|
#
|
65
|
+
# scope def search(field_values)
|
66
|
+
# field_values.inject(query) { |query, (field, value)|
|
67
|
+
# query.where(field => /#{value}/i)
|
68
|
+
# }
|
69
|
+
# end
|
70
|
+
#
|
97
71
|
# Returns nothing.
|
98
72
|
def scope(name, proc=nil, &block)
|
73
|
+
if method_defined?(name)
|
74
|
+
scope_method(name)
|
75
|
+
else
|
76
|
+
define_scope(name, proc || block)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
# Internal: Defines a new method that executes the passed proc or block in
|
83
|
+
# the context of the internal query object, and returns self.
|
84
|
+
def define_scope(name, proc)
|
99
85
|
define_method(name) do |*args|
|
100
|
-
@query = query.instance_exec *args, &
|
86
|
+
@query = query.instance_exec *args, &proc
|
101
87
|
self
|
102
88
|
end
|
103
89
|
end
|
104
90
|
|
105
|
-
#
|
106
|
-
#
|
107
|
-
|
108
|
-
|
109
|
-
def delegated_methods
|
110
|
-
Array.instance_methods - Object.instance_methods +
|
111
|
-
[:all, :where, :distinct, :group, :having, :includes, :joins, :limit, :offset, :order, :reverse_order] +
|
112
|
-
[:==, :as_json, :cache_key, :decorate]
|
91
|
+
# Public: Makes an existing method chainable by intercepting the call, and
|
92
|
+
# storing the result as the internal query, and returning self.
|
93
|
+
def scope_method(name)
|
94
|
+
prepend Module.new.tap { |s| s.module_eval Queryable.scope_method(name) }
|
113
95
|
end
|
114
96
|
end
|
97
|
+
|
98
|
+
# Internal: Generates the scope interceptor method.
|
99
|
+
#
|
100
|
+
# name - Name of the method to convert to a scope.
|
101
|
+
#
|
102
|
+
# Returns a String with the code of the scope method.
|
103
|
+
def self.scope_method(name)
|
104
|
+
<<-SCOPE
|
105
|
+
def #{name}(*args)
|
106
|
+
@query = super
|
107
|
+
self
|
108
|
+
end
|
109
|
+
SCOPE
|
110
|
+
end
|
111
|
+
|
112
|
+
# Internal: Default methods to be delegated to the internal query.
|
113
|
+
#
|
114
|
+
# Returns an Array with the name of the methods to delegate.
|
115
|
+
def self.default_delegated_methods
|
116
|
+
Array.instance_methods - Object.instance_methods +
|
117
|
+
[:all, :where, :distinct, :group, :having, :includes, :joins, :limit, :offset, :order, :reverse_order] +
|
118
|
+
[:==, :as_json, :cache_key, :decorate]
|
119
|
+
end
|
115
120
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# Public: Provides default initialization for query objects, most objects are
|
2
|
+
# mapped to a collection or table, the default query takes all of them.
|
3
|
+
module Queryable
|
4
|
+
module DefaultQuery
|
5
|
+
|
6
|
+
# Internal: Adds class methods, and default initialization.
|
7
|
+
def self.included(base)
|
8
|
+
base.extend ClassMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(query=self.class.default_query)
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
|
17
|
+
# Public: Sets the default table or collection for this query object.
|
18
|
+
#
|
19
|
+
# collection - A model or static query.
|
20
|
+
def queryable(collection)
|
21
|
+
@queryable_class = collection
|
22
|
+
end
|
23
|
+
|
24
|
+
# Internal: Default query for the object, can be overriden by subclasses.
|
25
|
+
#
|
26
|
+
# Returns a criteriable or chainable query of some sort.
|
27
|
+
def default_query
|
28
|
+
queryable_class.all
|
29
|
+
end
|
30
|
+
|
31
|
+
# Internal: The default table or collection for this query object.
|
32
|
+
# Provides a default based on a convention of the query object name.
|
33
|
+
def queryable_class
|
34
|
+
@queryable_class ||= if superclass.respond_to?(:queryable_class)
|
35
|
+
superclass.queryable_class || Object.const_get(name.gsub('sQuery', ''))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Public: Allows to define default scopes in query objects, and inherit them in
|
2
|
+
# query object subclasses.
|
3
|
+
module Queryable
|
4
|
+
module DefaultScope
|
5
|
+
|
6
|
+
# Internal: Adds class methods, and default initialization.
|
7
|
+
def self.included(base)
|
8
|
+
base.extend ClassMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(*args)
|
12
|
+
super
|
13
|
+
apply_default_scopes
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
# Internal: Applies all the default scopes to this query object.
|
19
|
+
def apply_default_scopes
|
20
|
+
self.class.default_scopes.each { |scope| apply_default_scope(scope) }
|
21
|
+
end
|
22
|
+
|
23
|
+
# Internal: Applies a default scope to this query object.
|
24
|
+
#
|
25
|
+
# scope - A method name Symbol, or a Proc.
|
26
|
+
#
|
27
|
+
def apply_default_scope(scope)
|
28
|
+
scope.is_a?(Proc) ? instance_exec(&scope) : send(scope)
|
29
|
+
end
|
30
|
+
|
31
|
+
module ClassMethods
|
32
|
+
|
33
|
+
# Public: Allows a class to set a default scope. Default scopes are
|
34
|
+
# chainable with inheritance, so a subclass also picks up the default
|
35
|
+
# scopes of the parent class.
|
36
|
+
#
|
37
|
+
# scope - A method name Symbol, or a Proc.
|
38
|
+
def default_scope(scope)
|
39
|
+
@default_scope = scope
|
40
|
+
end
|
41
|
+
|
42
|
+
# Internal: Returns the default scopes of the parent query objects.
|
43
|
+
def parent_scopes
|
44
|
+
superclass.respond_to?(:default_scopes) ? superclass.default_scopes : []
|
45
|
+
end
|
46
|
+
|
47
|
+
# Internal: Returns the default scopes that should be applied.
|
48
|
+
def default_scopes
|
49
|
+
@default_scopes ||= (parent_scopes + [@default_scope]).compact
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
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:
|
4
|
+
version: 2.0.0
|
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
|
+
date: 2014-08-12 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,6 +21,8 @@ extra_rdoc_files:
|
|
21
21
|
files:
|
22
22
|
- README.md
|
23
23
|
- lib/queryable.rb
|
24
|
+
- lib/queryable/default_query.rb
|
25
|
+
- lib/queryable/default_scope.rb
|
24
26
|
homepage: https://github.com/ElMassimo/queryable
|
25
27
|
licenses:
|
26
28
|
- MIT
|
@@ -47,4 +49,3 @@ signing_key:
|
|
47
49
|
specification_version: 4
|
48
50
|
summary: Keep your scopes and queries flexible by using Ruby
|
49
51
|
test_files: []
|
50
|
-
has_rdoc:
|