active_hash_relation 0.0.2 → 0.0.3

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: 60eec7b209bc819b5c4c678f9350022252ddb7f8
4
- data.tar.gz: 157845010e5961cdc7f12adf04fadb40f5369541
3
+ metadata.gz: c46ec26a67f7a3de70d6ea616c729d074b24b3c6
4
+ data.tar.gz: 77fcb4801781ce42b1b131897f512a27e99c14c4
5
5
  SHA512:
6
- metadata.gz: c357b72169fff0f28b4d9cb4b4a61941d8ebc478b80676a161ad176dbe741583b96582af699421389569816397a6487a589c070109ed4d9ab747db029b19fd52
7
- data.tar.gz: f614659c194e246c597a9dd4a780ac13f6eb2370101a0a0239191baa09275caacee53eddea951212560738ab6eeb0b3aefc6d372aa13f0ae9c1d94984dd77683
6
+ metadata.gz: fd1dd4b024765dacd505e2bf4b035ccfc5949c457404e650bbd2a0dc9cdd88bcdc1a661651a4a4d8476afb7309e5aed2920aedda563643bc37d64dbd6d358494
7
+ data.tar.gz: 467857eaaa1c5742190b336f36489d206a3ae59d068f4540948ad9f39a296bc479a5bed3c052e01c9495c71af687d14caf8f0d46d916c065aeed5c24790e19db
data/README.md CHANGED
@@ -23,6 +23,8 @@ on unknown attributes (attributes not returned from the API) by brute forcing
23
23
  which might or might not be a security issue. If you don't like that check
24
24
  [whitelisting](https://github.com/kollegorna/active_hash_relation#whitelisting)._
25
25
 
26
+ *New*! You can now do [__aggregation queries__](https://github.com/kollegorna/active_hash_relation#aggregation_queries).
27
+
26
28
  ## Installation
27
29
 
28
30
  Add this line to your application's Gemfile:
@@ -63,7 +65,7 @@ For each param, `apply_filters` method will search in the model's (derived from
63
65
  #### Primary
64
66
  You can apply a filter a column which is a primary key by value or using an array like:
65
67
  * `{primary_key_column: 5}`
66
- * `{primary_key)column: [1,3,4,5,6,7]}`
68
+ * `{primary_key_column: [1,3,4,5,6,7]}`
67
69
 
68
70
  #### Integer, Float, Decimal, Date, Time or Datetime/Timestamp
69
71
  You can apply an equality filter:
@@ -143,6 +145,28 @@ With the above settings, when the association name is `resource`,
143
145
  `Api::V1::ResourceFilter.new(resource, params[resource]).apply_filters` will be
144
146
  called to apply the filters in resource association.
145
147
 
148
+ ## Aggregation Queries
149
+ Sometimes we need to ask the database queries that act on the collection but don't want back an array of elements but a value instead! Now you can do that on an ActiveRecord::Relation by simply calling the aggregations method inside the controller:
150
+
151
+ ```ruby
152
+ apply_filters(resource, {
153
+ aggregate: {
154
+ integer_column: { avg: true, max: true, min: true, sum: true },
155
+ float_column: {avg: true, max: true, min: true },
156
+ datetime_column: { max: true, min: true }
157
+ }
158
+ })
159
+ ```
160
+
161
+ and you will get a hash (HashWithIndifferentAccess) back that holds all your aggregations like:
162
+ ```ruby
163
+ {"float_column"=>{"avg"=>25.5, "max"=>50, "min"=>1},
164
+ "integer_column"=>{"avg"=>4.38, "sum"=>219, "max"=>9, "min"=>0},
165
+ "datetime_at"=>{"max"=>2015-06-11 20:59:14 UTC, "min"=>2015-06-11 20:59:12 UTC}}
166
+ ```
167
+
168
+ These attributes usually go to the "meta" section of your serializer. In that way it's easy to parse them in the front-end (for ember check [here](http://guides.emberjs.com/v1.10.0/models/handling-metadata/). Please note that you should apply the aggregations __after__ you apply the filters, if there any.
169
+
146
170
 
147
171
 
148
172
  ## Contributing
@@ -0,0 +1,58 @@
1
+ module ActiveHashRelation
2
+ class Aggregation
3
+ include Helpers
4
+
5
+ attr_reader :configuration, :params, :resource, :model
6
+
7
+ def initialize(resource, params, model: nil)
8
+ @configuration = Module.nesting.last.configuration
9
+ @resource = resource
10
+ @params = HashWithIndifferentAccess.new(params)
11
+ @model = model
12
+
13
+ unless @model
14
+ @model = model_class_name(@resource)
15
+ end
16
+ end
17
+
18
+ def apply
19
+ if params[:aggregate].is_a? Hash
20
+ meta_attributes = HashWithIndifferentAccess.new
21
+
22
+ @model.columns.each do |c|
23
+ next unless params[:aggregate][c.name.to_s].is_a? Hash
24
+
25
+ case c.type
26
+ when :integer, :float, :decimal
27
+ meta_attributes[c.name.to_s] = apply_aggregations(
28
+ {avg: :average, sum: :sum, max: :maximum, min: :minimum},
29
+ params[:aggregate][c.name.to_s],
30
+ c.name.to_s
31
+ )
32
+ when :date, :datetime, :timestamp
33
+ meta_attributes[c.name.to_s] = apply_aggregations(
34
+ {max: :maximum, min: :minimum},
35
+ params[:aggregate][c.name.to_s],
36
+ c.name.to_s
37
+ )
38
+ end
39
+ end
40
+ end
41
+
42
+ return meta_attributes
43
+ end
44
+
45
+ def apply_aggregations(available_aggr, asked_aggr, column)
46
+ meta_attributes = HashWithIndifferentAccess.new
47
+
48
+ available_aggr.each do |k, v|
49
+ if asked_aggr[k] == true
50
+ meta_attributes[k] = resource.send(v,column)
51
+ meta_attributes[k] = meta_attributes[k].to_f if meta_attributes[k].is_a? BigDecimal
52
+ end
53
+ end
54
+
55
+ return meta_attributes
56
+ end
57
+ end
58
+ end
@@ -1,8 +1,4 @@
1
1
  module ActiveHashRelation::ColumnFilters
2
- def model_class_name(resource)
3
- resource.class.to_s.split('::').first.constantize
4
- end
5
-
6
2
  def filter_primary(resource, column, param)
7
3
  resource = resource.where(id: param)
8
4
  end
@@ -1,5 +1,6 @@
1
1
  module ActiveHashRelation
2
2
  class FilterApplier
3
+ include Helpers
3
4
  include ColumnFilters
4
5
  include AssociationFilters
5
6
  include ScopeFilters
@@ -0,0 +1,7 @@
1
+ module ActiveHashRelation
2
+ module Helpers
3
+ def model_class_name(resource)
4
+ resource.class.to_s.split('::').first.constantize
5
+ end
6
+ end
7
+ end
@@ -1,3 +1,3 @@
1
1
  module ActiveHashRelation
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -1,5 +1,6 @@
1
1
  require "active_record/scope_names"
2
2
  require "active_hash_relation/version"
3
+ require "active_hash_relation/helpers"
3
4
  require "active_hash_relation/column_filters"
4
5
  require "active_hash_relation/scope_filters"
5
6
  require "active_hash_relation/sort_filters"
@@ -7,6 +8,8 @@ require "active_hash_relation/limit_filters"
7
8
  require "active_hash_relation/association_filters"
8
9
  require "active_hash_relation/filter_applier"
9
10
 
11
+ require "active_hash_relation/aggregation"
12
+
10
13
  module ActiveHashRelation
11
14
  class << self
12
15
  attr_accessor :configuration
@@ -32,8 +35,11 @@ module ActiveHashRelation
32
35
  ).apply_filters
33
36
  end
34
37
 
38
+ def aggregations(resource, params)
39
+ Aggregation.new(resource, params).apply
40
+ end
41
+
35
42
  class Configuration
36
43
  attr_accessor :has_filter_classes, :filter_class_prefix, :filter_class_suffix
37
44
  end
38
-
39
45
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_hash_relation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Filippos Vasilakis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-05 00:00:00.000000000 Z
11
+ date: 2015-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -53,9 +53,11 @@ files:
53
53
  - Rakefile
54
54
  - active_hash_relation.gemspec
55
55
  - lib/active_hash_relation.rb
56
+ - lib/active_hash_relation/aggregation.rb
56
57
  - lib/active_hash_relation/association_filters.rb
57
58
  - lib/active_hash_relation/column_filters.rb
58
59
  - lib/active_hash_relation/filter_applier.rb
60
+ - lib/active_hash_relation/helpers.rb
59
61
  - lib/active_hash_relation/limit_filters.rb
60
62
  - lib/active_hash_relation/scope_filters.rb
61
63
  - lib/active_hash_relation/sort_filters.rb