queryable 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +93 -3
  3. data/lib/queryable.rb +13 -11
  4. metadata +2 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f519477ea7a61d9e99c9cff819433102ac236bcd
4
- data.tar.gz: 47402fda61136b8ceaae98d9c214b12ffb586df1
3
+ metadata.gz: d01fa7b43b3b44643d009f15e6438ef3fd4a665f
4
+ data.tar.gz: 75164b6c8f28fb3db7e6b182a3f18bf50aa386f8
5
5
  SHA512:
6
- metadata.gz: 632bbebc1ce1e6765892f2ac67d56fd91b0a71f57bc00dc057f502075095ec090298b00f7a7f174360dfda8cea8978c16595208f705f6a8955f0052fe662c63b
7
- data.tar.gz: 2b7d37a7463b29fbd5c81fb27bf948f914fff896cc286320eae3ba12686609a268c83d26dcd9dd5993a304ecaee5448d6913f8bf78665d2dd409c4024655cd18
6
+ metadata.gz: 994927851ef85e8a225f3cb8c21cac6eb21d9d97ac336ca7992d0b4594d8aafab58130e3d60e590b044f331fd7214b99b14fa00b5d56995b3bf0594d001c1b67
7
+ data.tar.gz: 4f0c6d2d977f9d5ba763c414f2fe434da06c089a8ca628e6358fba8899396fbd3c6a3fd0bfb80a597e44117a163b0e9870a417f6eb1ec5aef22080f76e8a77ea
data/README.md CHANGED
@@ -1,10 +1,100 @@
1
1
  Queryable
2
2
  =====================
3
+ [![Gem Version](https://badge.fury.io/rb/queryable.svg)](http://badge.fury.io/rb/queryable)
4
+ [![Build Status](https://travis-ci.org/ElMassimo/queryable.svg)](https://travis-ci.org/ElMassimo/queryable)
3
5
  [![Coverage Status](https://coveralls.io/repos/ElMassimo/queryable/badge.png)](https://coveralls.io/r/ElMassimo/queryable)
6
+ <!-- [![Code Climate](https://codeclimate.com/github/ElMassimo/queryable.png)](https://codeclimate.com/github/ElMassimo/queryable) -->
4
7
 
5
-
6
- Allows you to easily define query objects with chainable scopes.
8
+ Queryable is a mixin that allows you to easily define query objects with chainable scopes.
7
9
 
8
10
  ## Usage
11
+ ```ruby
12
+ class CustomerQuery
13
+ include Queryable
14
+
15
+ scope(:recent) { desc(:logged_in_at) }
16
+
17
+ scope :active, ->{ where(status: 'active') }
18
+
19
+ scope :favourite_brand do |product, brand|
20
+ where("favourites.#{product}": brand)
21
+ end
22
+
23
+ def current
24
+ recent.active
25
+ end
26
+
27
+ def miller_fans
28
+ favourite_brand(:beer, :Miller)
29
+ end
30
+
31
+ def search_in_current(field_values)
32
+ define_query do |customers|
33
+ field_values.inject(customers) { |customers, (field, value)|
34
+ customers.where(field => /#{value}/i)
35
+ }
36
+ end.current
37
+ end
38
+ end
39
+
40
+
41
+ CustomerQuery.new(shop.customers).miller_fans.search_in_current(last_name: 'M')
42
+ ```
43
+
44
+ ### Scopes
45
+
46
+ Scopes serve to encapsulate reusable business rules, a method is defined with
47
+ the selected name and block (or proc)
48
+
49
+ ### Define Query
50
+
51
+ While scopes are great because of their terseness, they can be limiting because
52
+ the block executes in the context of the internal query, so methods, constants,
53
+ and variables of the Queryable are not accessible.
54
+
55
+ For those cases, you can use `define_query`, which is a convenience setter for
56
+ the internal query, that also takes care of returning `self` at the end of the
57
+ call to make the methods chainable.
58
+
59
+ ## Advantages
60
+
61
+ * Query objects are easy to understand.
62
+ * You can inherit, mixin, and chain queries in a very natural way.
63
+ * Increased testability, pretty close to being ORM/ODM agnostic.
64
+
65
+ ## Testing
66
+
67
+ You can check the [specs](https://github.com/ElMassimo/queryable/tree/master/spec) of the project
68
+ to check how to test query objects without even having to require the ORM/ODM, or
69
+ you can test by requiring your ORM/ODM and executing queries as usual.
70
+
71
+ ## RDocs
72
+
73
+ You can view the **Queryable** documentation in RDoc format here:
74
+
75
+ http://rubydoc.info/github/ElMassimo/queryable/master/frames
76
+
77
+
78
+ License
79
+ --------
80
+
81
+ Copyright (c) 2014 Máximo Mussini
82
+
83
+ Permission is hereby granted, free of charge, to any person obtaining
84
+ a copy of this software and associated documentation files (the
85
+ "Software"), to deal in the Software without restriction, including
86
+ without limitation the rights to use, copy, modify, merge, publish,
87
+ distribute, sublicense, and/or sell copies of the Software, and to
88
+ permit persons to whom the Software is furnished to do so, subject to
89
+ the following conditions:
90
+
91
+ The above copyright notice and this permission notice shall be
92
+ included in all copies or substantial portions of the Software.
9
93
 
10
- ## Background
94
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
95
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
96
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
97
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
98
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
99
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
100
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/lib/queryable.rb CHANGED
@@ -1,6 +1,3 @@
1
- require 'active_support/concern'
2
- require 'active_support/core_ext/module/delegation'
3
-
4
1
  # Public: Mixin that adds Queryable functionality to a plain ruby object.
5
2
  # A Queryable manages an internal query object, and defines chainable methods
6
3
  # that interact with the query object, modifying its value.
@@ -14,13 +11,18 @@ require 'active_support/core_ext/module/delegation'
14
11
  # end
15
12
  #
16
13
  module Queryable
17
- extend ActiveSupport::Concern
18
14
 
19
- included do
20
- # Public: Gets/Sets the internal query.
21
- attr_accessor :query
15
+ # Internal: Adds class methods, a query accessor, and method delegation.
16
+ def self.included(base)
17
+ base.extend ClassMethods
18
+ base.extend Forwardable
19
+ base.class_eval do
20
+
21
+ # Public: Gets/Sets the internal query.
22
+ attr_accessor :query
22
23
 
23
- delegate *delegated_methods, to: :query
24
+ def_delegators :query, *delegated_methods
25
+ end
24
26
  end
25
27
 
26
28
  # Public: Initialize a Queryable with a query.
@@ -54,9 +56,9 @@ module Queryable
54
56
  #
55
57
  # # Extracted from a scope for clarity.
56
58
  # def search(field_values)
57
- # define_query do |user|
58
- # field_values.inject(user) { |user, (field, value)|
59
- # user.where(field => /#{value}/i)
59
+ # define_query do |users|
60
+ # field_values.inject(users) { |users, (field, value)|
61
+ # users.where(field => /#{value}/i)
60
62
  # }
61
63
  # end
62
64
  # end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: queryable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Máximo Mussini
@@ -9,21 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2014-04-12 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: activesupport
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
12
+ dependencies: []
27
13
  description: Queryable is a module that encapsulates query building so you don't have
28
14
  to tuck scopes inside your models.
29
15
  email: