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