queryable 1.0.0

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 +7 -0
  2. data/README.md +10 -0
  3. data/lib/queryable.rb +113 -0
  4. metadata +64 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f519477ea7a61d9e99c9cff819433102ac236bcd
4
+ data.tar.gz: 47402fda61136b8ceaae98d9c214b12ffb586df1
5
+ SHA512:
6
+ metadata.gz: 632bbebc1ce1e6765892f2ac67d56fd91b0a71f57bc00dc057f502075095ec090298b00f7a7f174360dfda8cea8978c16595208f705f6a8955f0052fe662c63b
7
+ data.tar.gz: 2b7d37a7463b29fbd5c81fb27bf948f914fff896cc286320eae3ba12686609a268c83d26dcd9dd5993a304ecaee5448d6913f8bf78665d2dd409c4024655cd18
data/README.md ADDED
@@ -0,0 +1,10 @@
1
+ Queryable
2
+ =====================
3
+ [![Coverage Status](https://coveralls.io/repos/ElMassimo/queryable/badge.png)](https://coveralls.io/r/ElMassimo/queryable)
4
+
5
+
6
+ Allows you to easily define query objects with chainable scopes.
7
+
8
+ ## Usage
9
+
10
+ ## Background
data/lib/queryable.rb ADDED
@@ -0,0 +1,113 @@
1
+ require 'active_support/concern'
2
+ require 'active_support/core_ext/module/delegation'
3
+
4
+ # Public: Mixin that adds Queryable functionality to a plain ruby object.
5
+ # A Queryable manages an internal query object, and defines chainable methods
6
+ # that interact with the query object, modifying its value.
7
+ # It's designed to work well with both Mongoid and ActiveRecord.
8
+ #
9
+ # Examples
10
+ #
11
+ # class PersonQuery
12
+ # include Queryable
13
+ # scope(:too_damn_high) { where(:level.gt => 9000) }
14
+ # end
15
+ #
16
+ module Queryable
17
+ extend ActiveSupport::Concern
18
+
19
+ included do
20
+ # Public: Gets/Sets the internal query.
21
+ attr_accessor :query
22
+
23
+ delegate *delegated_methods, to: :query
24
+ end
25
+
26
+ # Public: Initialize a Queryable with a query.
27
+ #
28
+ # query - The internal query to build upon.
29
+ def initialize(query)
30
+ @query = query.all
31
+ end
32
+
33
+ # Public: Convenience setter for the internal query that returns self. The
34
+ # query is set to the value returned by the block. Useful when you need to
35
+ # access the context of the Queryable in addition to the query.
36
+ #
37
+ # block - A block that returns the new value of the internal query.
38
+ #
39
+ # Yields the internal query, which can be used to build upon.
40
+ # def search(query)
41
+ #
42
+ # Examples
43
+ #
44
+ # # Accessing a constant in the Queryable object context.
45
+ # LATEST_COUNT = 10
46
+ # def latest
47
+ # define_query {|query| query.limit(LATEST_COUNT) }
48
+ # end
49
+ #
50
+ # # We use it because the last method we chain does not return self.
51
+ # def recent_by_name
52
+ # define_query { recent.order(:name) }
53
+ # end
54
+ #
55
+ # # Extracted from a scope for clarity.
56
+ # def search(field_values)
57
+ # define_query do |user|
58
+ # field_values.inject(user) { |user, (field, value)|
59
+ # user.where(field => /#{value}/i)
60
+ # }
61
+ # end
62
+ # end
63
+ #
64
+ # Returns the Queryable object itself (self).
65
+ def define_query
66
+ @query = yield(query)
67
+ self
68
+ end
69
+
70
+ # Internal: Contains the Queryable class methods.
71
+ module ClassMethods
72
+ # Public: Defines a new method that executes the passed proc or block in
73
+ # the context of the internal query object, and returns self.
74
+ #
75
+ # name - Name of the scope to define for this Queryable.
76
+ #
77
+ # proc - An optional proc or lambda to be executed in the context of the
78
+ # the current query.
79
+ #
80
+ # block - An optional block to be executed in the context of the current
81
+ # query.
82
+ #
83
+ # Yields the arguments given to the scope when invoked, generally none.
84
+ #
85
+ # Examples
86
+ #
87
+ # scope :active, ->{ where(status: 'active') }
88
+ #
89
+ # scope(:recent) { desc(:created_at) }
90
+ #
91
+ # scope :of_brand do |brand|
92
+ # where(_type: "#{brand}ExtremelyFastRacingCar")
93
+ # end
94
+ #
95
+ # Returns nothing.
96
+ def scope(name, proc=nil, &block)
97
+ define_method(name) do |*args|
98
+ @query = query.instance_exec *args, &(proc || block)
99
+ self
100
+ end
101
+ end
102
+
103
+ # Internal: Methods to be delegated to the internal query. Method
104
+ # can be safely overriden to add or remove methods to delegate.
105
+ #
106
+ # Returns an Array with the name of the methods to delegate.
107
+ def delegated_methods
108
+ Array.instance_methods - Object.instance_methods +
109
+ [:all, :where, :distinct, :group, :having, :includes, :joins, :limit, :offset, :order, :reverse_order] +
110
+ [:==, :as_json, :cache_key, :decorate]
111
+ end
112
+ end
113
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: queryable
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Máximo Mussini
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
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'
27
+ description: Queryable is a module that encapsulates query building so you don't have
28
+ to tuck scopes inside your models.
29
+ email:
30
+ - maximomussini@gmail.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files:
34
+ - README.md
35
+ files:
36
+ - README.md
37
+ - lib/queryable.rb
38
+ homepage: https://github.com/ElMassimo/queryable
39
+ licenses:
40
+ - MIT
41
+ metadata: {}
42
+ post_install_message:
43
+ rdoc_options:
44
+ - "--charset=UTF-8"
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: 1.9.3
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 2.2.2
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: Keep your scopes and queries flexible by using Ruby
63
+ test_files: []
64
+ has_rdoc: