active_hash_relation 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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