active_hash_relation 0.0.1 → 0.0.2
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 +43 -1
- data/lib/active_hash_relation.rb +22 -0
- data/lib/active_hash_relation/association_filters.rb +13 -5
- data/lib/active_hash_relation/column_filters.rb +2 -2
- data/lib/active_hash_relation/filter_applier.rb +24 -3
- data/lib/active_hash_relation/limit_filters.rb +5 -0
- data/lib/active_hash_relation/sort_filters.rb +9 -0
- data/lib/active_hash_relation/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 60eec7b209bc819b5c4c678f9350022252ddb7f8
|
4
|
+
data.tar.gz: 157845010e5961cdc7f12adf04fadb40f5369541
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c357b72169fff0f28b4d9cb4b4a61941d8ebc478b80676a161ad176dbe741583b96582af699421389569816397a6487a589c070109ed4d9ab747db029b19fd52
|
7
|
+
data.tar.gz: f614659c194e246c597a9dd4a780ac13f6eb2370101a0a0239191baa09275caacee53eddea951212560738ab6eeb0b3aefc6d372aa13f0ae9c1d94984dd77683
|
data/README.md
CHANGED
@@ -13,7 +13,15 @@ or even filter a resource based on it's associations' associations:
|
|
13
13
|
```ruby
|
14
14
|
apply_filters(resource, {updated_at: { geq: "2014-11-2 14:25:04"}, unit: {id: 9, areas: {id: 22} }})
|
15
15
|
```
|
16
|
-
and the list could go on.. Basically your whole db is exposed there. It's perfect for filtering a collection of resources on APIs.
|
16
|
+
and the list could go on.. Basically your whole db is exposed\* there. It's perfect for filtering a collection of resources on APIs.
|
17
|
+
|
18
|
+
It should be noted that `apply_filters` calls `ActiveHashRelation::FilterApplier` class
|
19
|
+
underneath with the same params.
|
20
|
+
|
21
|
+
_\*Actually nothing is exposed, but a user could retrieve resources based
|
22
|
+
on unknown attributes (attributes not returned from the API) by brute forcing
|
23
|
+
which might or might not be a security issue. If you don't like that check
|
24
|
+
[whitelisting](https://github.com/kollegorna/active_hash_relation#whitelisting)._
|
17
25
|
|
18
26
|
## Installation
|
19
27
|
|
@@ -82,6 +90,19 @@ You can apply an incensitive matching filter (currently working only for Postgre
|
|
82
90
|
|
83
91
|
The above filter will search all records that include `test` in the `example_column` field. A better would be nice here, for instance, setting the search sensitive or insensitive, start or end with a string etch
|
84
92
|
|
93
|
+
### Limit
|
94
|
+
A limit param defines the number of returned resources. For instance:
|
95
|
+
* `{limit: 10}`
|
96
|
+
|
97
|
+
However I would strongly advice you to use a pagination gem like Kaminari, and use `page` and `per_page` params.
|
98
|
+
|
99
|
+
|
100
|
+
### Sorting
|
101
|
+
You can apply sorting using the `property` and `order` attributes. For instance:
|
102
|
+
* `{property: 'created_at', order: 'desc'}`
|
103
|
+
|
104
|
+
If there is no column named after the property value, sorting is skipped.
|
105
|
+
|
85
106
|
|
86
107
|
### Associations
|
87
108
|
If the association is a `belongs_to` or `has_one`, then the hash key name must be in singular. If the association is `has_many` the attribute must be in plural reflecting the association type. When you have, in your hash, filters for an association, the sub-hash is passed in the association's model. For instance, let's say a user has many microposts and the following filter is applied (could be through an HTTP GET request on controller's index method):
|
@@ -103,6 +124,27 @@ will run the `.planned` scope on the resource.
|
|
103
124
|
### Whitelisting
|
104
125
|
If you don't want to allow a column/association/scope just remove it from the params hash.
|
105
126
|
|
127
|
+
#### Filter Classes
|
128
|
+
Sometimes, especially on larger projects, you have specific classes that handle
|
129
|
+
the input params outside the controllers. You can configure the gem to look for
|
130
|
+
those classes and call `apply_filters` which will apply the necessary filters when
|
131
|
+
iterating over associations.
|
132
|
+
|
133
|
+
In an initializer:
|
134
|
+
```ruby
|
135
|
+
#config/initializers/active_hash_relation.rb
|
136
|
+
ActiveHashRelation.configure do |config|
|
137
|
+
config.has_filter_classes = true
|
138
|
+
config.filter_class_prefix = 'Api::V1::'
|
139
|
+
config.filter_class_suffix = 'Filter'
|
140
|
+
end
|
141
|
+
```
|
142
|
+
With the above settings, when the association name is `resource`,
|
143
|
+
`Api::V1::ResourceFilter.new(resource, params[resource]).apply_filters` will be
|
144
|
+
called to apply the filters in resource association.
|
145
|
+
|
146
|
+
|
147
|
+
|
106
148
|
## Contributing
|
107
149
|
|
108
150
|
1. Fork it ( https://github.com/[my-github-username]/active_hash_relation/fork )
|
data/lib/active_hash_relation.rb
CHANGED
@@ -2,10 +2,27 @@ require "active_record/scope_names"
|
|
2
2
|
require "active_hash_relation/version"
|
3
3
|
require "active_hash_relation/column_filters"
|
4
4
|
require "active_hash_relation/scope_filters"
|
5
|
+
require "active_hash_relation/sort_filters"
|
6
|
+
require "active_hash_relation/limit_filters"
|
5
7
|
require "active_hash_relation/association_filters"
|
6
8
|
require "active_hash_relation/filter_applier"
|
7
9
|
|
8
10
|
module ActiveHashRelation
|
11
|
+
class << self
|
12
|
+
attr_accessor :configuration
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.configure
|
16
|
+
self.configuration
|
17
|
+
yield(configuration)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.configuration
|
21
|
+
@configuration ||= Configuration.new do
|
22
|
+
self.has_filter_classes = false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
9
26
|
def apply_filters(resource, params, include_associations: false, model: nil)
|
10
27
|
FilterApplier.new(
|
11
28
|
resource,
|
@@ -14,4 +31,9 @@ module ActiveHashRelation
|
|
14
31
|
model: model
|
15
32
|
).apply_filters
|
16
33
|
end
|
34
|
+
|
35
|
+
class Configuration
|
36
|
+
attr_accessor :has_filter_classes, :filter_class_prefix, :filter_class_suffix
|
37
|
+
end
|
38
|
+
|
17
39
|
end
|
@@ -7,11 +7,19 @@ module ActiveHashRelation::AssociationFilters
|
|
7
7
|
model.reflect_on_all_associations.map(&:name).each do |association|
|
8
8
|
if params[association]
|
9
9
|
association_name = association.to_s.titleize.split.join
|
10
|
-
|
11
|
-
association_name
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
if self.configuration.has_filter_classes
|
11
|
+
puts self.filter_class(association_name)
|
12
|
+
association_filters = self.filter_class(association_name).new(
|
13
|
+
association_name.singularize.constantize.all,
|
14
|
+
params[association]
|
15
|
+
).apply_filters
|
16
|
+
else
|
17
|
+
association_filters = ActiveHashRelation::FilterApplier.new(
|
18
|
+
association_name.singularize.constantize.all,
|
19
|
+
params[association],
|
20
|
+
include_associations: true
|
21
|
+
).apply_filters
|
22
|
+
end
|
15
23
|
resource = resource.joins(association).merge(association_filters)
|
16
24
|
end
|
17
25
|
end
|
@@ -63,13 +63,13 @@ module ActiveHashRelation::ColumnFilters
|
|
63
63
|
if param[:leq]
|
64
64
|
resource = resource.where("#{table_name}.#{column} <= ?", param[:leq])
|
65
65
|
elsif param[:le]
|
66
|
-
resource = resource.where("#{table_name}.#{column} < ?", param[:
|
66
|
+
resource = resource.where("#{table_name}.#{column} < ?", param[:le])
|
67
67
|
end
|
68
68
|
|
69
69
|
if param[:geq]
|
70
70
|
resource = resource.where("#{table_name}.#{column} >= ?", param[:geq])
|
71
71
|
elsif param[:ge]
|
72
|
-
resource = resource.where("#{table_name}.#{column} > ?", param[:
|
72
|
+
resource = resource.where("#{table_name}.#{column} > ?", param[:ge])
|
73
73
|
end
|
74
74
|
|
75
75
|
return resource
|
@@ -3,8 +3,13 @@ module ActiveHashRelation
|
|
3
3
|
include ColumnFilters
|
4
4
|
include AssociationFilters
|
5
5
|
include ScopeFilters
|
6
|
+
include SortFilters
|
7
|
+
include LimitFilters
|
6
8
|
|
7
|
-
|
9
|
+
attr_reader :configuration
|
10
|
+
|
11
|
+
def initialize(resource, params, include_associations: true, model: nil)
|
12
|
+
@configuration = Module.nesting.last.configuration
|
8
13
|
@resource = resource
|
9
14
|
@params = HashWithIndifferentAccess.new(params)
|
10
15
|
@include_associations = include_associations
|
@@ -20,7 +25,18 @@ module ActiveHashRelation
|
|
20
25
|
@model.columns.each do |c|
|
21
26
|
next if @params[c.name.to_s].nil?
|
22
27
|
|
23
|
-
|
28
|
+
if c.respond_to?(:primary)
|
29
|
+
if c.primary
|
30
|
+
@resource = filter_primary(@resource, c.name, @params[c.name])
|
31
|
+
next
|
32
|
+
end
|
33
|
+
else #rails 4.2
|
34
|
+
if @model.primary_key == c.name
|
35
|
+
@resource = filter_primary(@resource, c.name, @params[c.name])
|
36
|
+
next
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
24
40
|
case c.type
|
25
41
|
when :integer
|
26
42
|
@resource = filter_integer(@resource, c.name, table_name, @params[c.name])
|
@@ -41,10 +57,15 @@ module ActiveHashRelation
|
|
41
57
|
|
42
58
|
|
43
59
|
@resource = filter_scopes(@resource, @params[:scopes]) if @params.include?(:scopes)
|
44
|
-
@resource = filter_associations(@resource, @params)
|
60
|
+
@resource = filter_associations(@resource, @params) if @include_associations
|
61
|
+
@resource = apply_limit(@resource, @params[:limit]) if @params.include?(:limit)
|
62
|
+
@resource = apply_sort(@resource, @params[:sort], @model) if @params.include?(:sort)
|
45
63
|
|
46
64
|
return @resource
|
47
65
|
end
|
48
66
|
|
67
|
+
def filter_class(resource_name)
|
68
|
+
"#{configuration.filter_class_prefix}#{resource_name.pluralize}#{configuration.filter_class_suffix}".constantize
|
69
|
+
end
|
49
70
|
end
|
50
71
|
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.
|
4
|
+
version: 0.0.2
|
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-
|
11
|
+
date: 2015-05-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -56,7 +56,9 @@ files:
|
|
56
56
|
- lib/active_hash_relation/association_filters.rb
|
57
57
|
- lib/active_hash_relation/column_filters.rb
|
58
58
|
- lib/active_hash_relation/filter_applier.rb
|
59
|
+
- lib/active_hash_relation/limit_filters.rb
|
59
60
|
- lib/active_hash_relation/scope_filters.rb
|
61
|
+
- lib/active_hash_relation/sort_filters.rb
|
60
62
|
- lib/active_hash_relation/version.rb
|
61
63
|
- lib/active_record/scope_names.rb
|
62
64
|
homepage: https://www.kollegorna.se
|