fetcheable_on_api 0.2.5 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +4 -4
- data/README.md +1 -1
- data/lib/fetcheable_on_api/configuration.rb +3 -1
- data/lib/fetcheable_on_api/{filtreable.rb → filterable.rb} +19 -15
- data/lib/fetcheable_on_api/pageable.rb +71 -0
- data/lib/fetcheable_on_api/sortable.rb +10 -3
- data/lib/fetcheable_on_api/version.rb +1 -1
- data/lib/fetcheable_on_api.rb +31 -28
- metadata +4 -4
- data/lib/fetcheable_on_api/pagineable.rb +0 -55
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 74add540213b83da4a66b0659825527d544b188886486eca78205f19788a3f4a
|
4
|
+
data.tar.gz: 607fd13d633c56609925a94d609ac0584ad1b63ace98c420aff7e2191da4a701
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4be9be92db3e5c4daf9be7c044f4426fbe7a07ddc3342f0b9934fbd4fe91f3af87e6af626a1a17b47f5bc9208c9e8a04102e80d29afaf38af840623e53a1e215
|
7
|
+
data.tar.gz: 813718d44919c9b51e8168914cda8fb2956e44e256829461bcc7b1d5e067ccbfa8c74a4120573f5f1905d397570cbe26ed2e34e0afd1f05e17d561718b86f551
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
fetcheable_on_api (0.2.
|
4
|
+
fetcheable_on_api (0.2.4)
|
5
5
|
activesupport (>= 4.1)
|
6
6
|
|
7
7
|
GEM
|
@@ -13,9 +13,9 @@ GEM
|
|
13
13
|
minitest (~> 5.1)
|
14
14
|
tzinfo (~> 1.1)
|
15
15
|
ast (2.4.0)
|
16
|
-
concurrent-ruby (1.1.
|
16
|
+
concurrent-ruby (1.1.4)
|
17
17
|
diff-lcs (1.3)
|
18
|
-
i18n (1.
|
18
|
+
i18n (1.5.3)
|
19
19
|
concurrent-ruby (~> 1.0)
|
20
20
|
jaro_winkler (1.5.1)
|
21
21
|
minitest (5.11.3)
|
@@ -63,4 +63,4 @@ DEPENDENCIES
|
|
63
63
|
rubocop (~> 0.59.2)
|
64
64
|
|
65
65
|
BUNDLED WITH
|
66
|
-
1.17.
|
66
|
+
1.17.3
|
data/README.md
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module FetcheableOnApi
|
4
|
-
#
|
4
|
+
# FetcheableOnApi configuration object.
|
5
|
+
#
|
5
6
|
class Configuration
|
7
|
+
# @attribute [Integer] Default pagination size
|
6
8
|
attr_accessor :pagination_default_size
|
7
9
|
|
8
10
|
def initialize
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module FetcheableOnApi
|
4
|
-
#
|
5
|
-
module
|
4
|
+
# Filterable implements `filter` parameter support.
|
5
|
+
module Filterable
|
6
6
|
#
|
7
|
-
#
|
7
|
+
# Predicates supported for filtering.
|
8
8
|
#
|
9
9
|
PREDICATES_WITH_ARRAY = %i[
|
10
10
|
does_not_match_all
|
@@ -40,8 +40,16 @@ module FetcheableOnApi
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
#
|
43
|
+
# Class methods made available to your controllers.
|
44
44
|
module ClassMethods
|
45
|
+
# Define a filterable attribute.
|
46
|
+
#
|
47
|
+
# @see FetcheableOnApi::Filterable::PREDICATES_WITH_ARRAY
|
48
|
+
#
|
49
|
+
# @param attrs [Array] options to define one or more filters.
|
50
|
+
# @option attrs [String, nil] :as Alias the filtered attribute
|
51
|
+
# @option attrs [String, nil] :class_name Override the class of the filter target
|
52
|
+
# @option attrs [String, nil] :with Use a specific predicate
|
45
53
|
def filter_by(*attrs)
|
46
54
|
options = attrs.extract_options!
|
47
55
|
options.symbolize_keys!
|
@@ -51,7 +59,7 @@ module FetcheableOnApi
|
|
51
59
|
|
52
60
|
attrs.each do |attr|
|
53
61
|
filters_configuration[attr] ||= {
|
54
|
-
as: options[:as] || attr
|
62
|
+
as: options[:as] || attr,
|
55
63
|
}
|
56
64
|
|
57
65
|
filters_configuration[attr].merge!(options)
|
@@ -68,10 +76,6 @@ module FetcheableOnApi
|
|
68
76
|
#
|
69
77
|
protected
|
70
78
|
|
71
|
-
# def convert_to_datetime(array)
|
72
|
-
# array.map { |el| foa_string_to_datetime(el.to_s) }
|
73
|
-
# end
|
74
|
-
|
75
79
|
def valid_keys
|
76
80
|
keys = filters_configuration.keys
|
77
81
|
keys.each_with_index do |key, index|
|
@@ -79,7 +83,7 @@ module FetcheableOnApi
|
|
79
83
|
next if predicate.respond_to?(:call) ||
|
80
84
|
PREDICATES_WITH_ARRAY.exclude?(predicate.to_sym)
|
81
85
|
|
82
|
-
keys[index] = {
|
86
|
+
keys[index] = {key => []}
|
83
87
|
end
|
84
88
|
|
85
89
|
keys
|
@@ -95,17 +99,17 @@ module FetcheableOnApi
|
|
95
99
|
.to_hash
|
96
100
|
|
97
101
|
filtering = filter_params.map do |column, values|
|
98
|
-
format
|
102
|
+
format = filters_configuration[column.to_sym].fetch(:format, :string)
|
99
103
|
column_name = filters_configuration[column.to_sym].fetch(:as, column)
|
100
|
-
klass
|
101
|
-
predicate
|
104
|
+
klass = filters_configuration[column.to_sym].fetch(:class_name, collection.klass)
|
105
|
+
predicate = filters_configuration[column.to_sym].fetch(:with, :ilike)
|
102
106
|
|
103
107
|
if values.is_a?(String)
|
104
|
-
values.split(
|
108
|
+
values.split(",").map do |value|
|
105
109
|
predicates(predicate, collection, klass, column_name, value)
|
106
110
|
end.inject(:or)
|
107
111
|
else
|
108
|
-
values.map! { |el| el.split(
|
112
|
+
values.map! { |el| el.split(",") }
|
109
113
|
predicates(predicate, collection, klass, column_name, values)
|
110
114
|
end
|
111
115
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FetcheableOnApi
|
4
|
+
# Pageable implements pagination support.
|
5
|
+
#
|
6
|
+
# It handles the controller parameters:
|
7
|
+
#
|
8
|
+
# - <code>page[:number]</code> the requested page (default: 1).
|
9
|
+
# - <code>page[:size]</code> number of records per page.
|
10
|
+
#
|
11
|
+
# If no <code>page</code> parameter is present on the request, the full collection is
|
12
|
+
# returned.
|
13
|
+
#
|
14
|
+
# The following pagination information is add to the response headers:
|
15
|
+
#
|
16
|
+
# - <code>Pagination-Current-Page</code> the page that is returned.
|
17
|
+
# - <code>Pagination-Per</code> the number of records included in the page.
|
18
|
+
# - <code>Pagination-Total-Pages</code> the total number of pages available.
|
19
|
+
# - <code>Pagination-Total-Count</code> the total number of records available.
|
20
|
+
#
|
21
|
+
module Pageable
|
22
|
+
#
|
23
|
+
# Supports
|
24
|
+
#
|
25
|
+
|
26
|
+
#
|
27
|
+
# Public class methods
|
28
|
+
#
|
29
|
+
|
30
|
+
#
|
31
|
+
# Public instance methods
|
32
|
+
#
|
33
|
+
|
34
|
+
#
|
35
|
+
# Protected instance methods
|
36
|
+
#
|
37
|
+
protected
|
38
|
+
|
39
|
+
def apply_pagination(collection)
|
40
|
+
return collection if params[:page].blank?
|
41
|
+
|
42
|
+
foa_valid_parameters!(:page)
|
43
|
+
|
44
|
+
limit, offset, count, page = extract_pagination_informations(collection)
|
45
|
+
define_header_pagination(limit, count, page)
|
46
|
+
|
47
|
+
collection.limit(limit).offset(offset)
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def define_header_pagination(limit, count, page)
|
53
|
+
response.headers["Pagination-Current-Page"] = page
|
54
|
+
response.headers["Pagination-Per"] = limit
|
55
|
+
response.headers["Pagination-Total-Pages"] = 1 + (count / limit).ceil
|
56
|
+
response.headers["Pagination-Total-Count"] = count
|
57
|
+
end
|
58
|
+
|
59
|
+
def extract_pagination_informations(collection)
|
60
|
+
limit = params[:page].fetch(
|
61
|
+
:size, FetcheableOnApi.configuration.pagination_default_size
|
62
|
+
).to_i
|
63
|
+
|
64
|
+
page = params[:page].fetch(:number, 1).to_i
|
65
|
+
offset = (page - 1) * limit
|
66
|
+
count = collection.except(:offset, :limit, :order).count
|
67
|
+
|
68
|
+
[limit, offset, count, page]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module FetcheableOnApi
|
4
|
-
#
|
4
|
+
# Sortable implements `pagination` support.
|
5
5
|
module Sortable
|
6
6
|
#
|
7
|
-
#
|
7
|
+
# Map of symbol to sorting direction supported by the module.
|
8
8
|
#
|
9
9
|
SORT_ORDER = {
|
10
10
|
"+" => :asc,
|
@@ -22,8 +22,15 @@ module FetcheableOnApi
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
#
|
25
|
+
# Class methods made available to your controllers.
|
26
26
|
module ClassMethods
|
27
|
+
# Define one ore more sortable attribute configurations.
|
28
|
+
#
|
29
|
+
# @param attrs [Array] options to define one or more sorting
|
30
|
+
# configurations.
|
31
|
+
# @option attrs [String, nil] :as Alias the sorted attribute
|
32
|
+
# @option attrs [true, false, nil] :with Wether to sort on the lowercase
|
33
|
+
# attribute value.
|
27
34
|
def sort_by(*attrs)
|
28
35
|
options = attrs.extract_options!
|
29
36
|
options.symbolize_keys!
|
data/lib/fetcheable_on_api.rb
CHANGED
@@ -1,31 +1,36 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
|
11
|
-
#
|
12
|
-
#
|
3
|
+
require "fetcheable_on_api/configuration"
|
4
|
+
require "fetcheable_on_api/filterable"
|
5
|
+
require "fetcheable_on_api/pageable"
|
6
|
+
require "fetcheable_on_api/sortable"
|
7
|
+
require "fetcheable_on_api/version"
|
8
|
+
require "active_support"
|
9
|
+
require "date"
|
10
|
+
|
11
|
+
# FetcheableOnApi provides standardized sorting, filtering and pagination for
|
12
|
+
# you API controllers.
|
13
|
+
#
|
13
14
|
module FetcheableOnApi
|
14
15
|
#
|
15
|
-
#
|
16
|
+
# Global configuration settings for FetcheableOnApi
|
16
17
|
#
|
17
|
-
#
|
18
|
-
# FetcheableOnApi.
|
19
|
-
#
|
20
|
-
#
|
21
|
-
class << self
|
22
|
-
attr_accessor :configuration
|
23
|
-
end
|
24
|
-
|
18
|
+
# @example Set default pagination size
|
19
|
+
# FetcheableOnApi.configuration.pagination_default_size = 25
|
20
|
+
#
|
21
|
+
# @return [Configuration] The global configuration instance
|
25
22
|
def self.configuration
|
26
23
|
@configuration ||= Configuration.new
|
27
24
|
end
|
28
25
|
|
26
|
+
# Configure FetcheableOnApi using a block.
|
27
|
+
#
|
28
|
+
# @example Set default pagination size
|
29
|
+
# FetcheableOnApi.configure do |config|
|
30
|
+
# config.pagination_default_size = 25
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# @yield [Configuration] Gives the global instance to the block.
|
29
34
|
def self.configure
|
30
35
|
yield(configuration)
|
31
36
|
end
|
@@ -33,7 +38,7 @@ module FetcheableOnApi
|
|
33
38
|
#
|
34
39
|
# Supports
|
35
40
|
#
|
36
|
-
ArgumentError
|
41
|
+
ArgumentError = Class.new(ArgumentError)
|
37
42
|
NotImplementedError = Class.new(NotImplementedError)
|
38
43
|
|
39
44
|
#
|
@@ -41,9 +46,9 @@ module FetcheableOnApi
|
|
41
46
|
#
|
42
47
|
def self.included(klass)
|
43
48
|
klass.class_eval do
|
44
|
-
include
|
49
|
+
include Filterable
|
45
50
|
include Sortable
|
46
|
-
include
|
51
|
+
include Pageable
|
47
52
|
end
|
48
53
|
end
|
49
54
|
|
@@ -66,11 +71,10 @@ module FetcheableOnApi
|
|
66
71
|
|
67
72
|
# Checks if the type of arguments is included in the permitted types
|
68
73
|
def foa_valid_parameters!(
|
69
|
-
|
70
|
-
)
|
74
|
+
*keys, foa_permitted_types: foa_default_permitted_types)
|
71
75
|
return if foa_valid_params_types(
|
72
76
|
*keys,
|
73
|
-
|
77
|
+
foa_permitted_types: foa_permitted_types,
|
74
78
|
)
|
75
79
|
|
76
80
|
raise FetcheableOnApi::ArgumentError,
|
@@ -78,8 +82,7 @@ module FetcheableOnApi
|
|
78
82
|
end
|
79
83
|
|
80
84
|
def foa_valid_params_types(
|
81
|
-
|
82
|
-
)
|
85
|
+
*keys, foa_permitted_types: foa_default_permitted_types)
|
83
86
|
foa_permitted_types.inject(false) do |res, type|
|
84
87
|
res || foa_valid_params_type(params.dig(*keys), type)
|
85
88
|
end
|
@@ -99,7 +102,7 @@ module FetcheableOnApi
|
|
99
102
|
|
100
103
|
# Convert string to datetime.
|
101
104
|
def foa_string_to_datetime(string)
|
102
|
-
DateTime.strptime(string,
|
105
|
+
DateTime.strptime(string, "%s")
|
103
106
|
end
|
104
107
|
end
|
105
108
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fetcheable_on_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fabien
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-01-
|
11
|
+
date: 2019-01-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -95,8 +95,8 @@ files:
|
|
95
95
|
- Rakefile
|
96
96
|
- lib/fetcheable_on_api.rb
|
97
97
|
- lib/fetcheable_on_api/configuration.rb
|
98
|
-
- lib/fetcheable_on_api/
|
99
|
-
- lib/fetcheable_on_api/
|
98
|
+
- lib/fetcheable_on_api/filterable.rb
|
99
|
+
- lib/fetcheable_on_api/pageable.rb
|
100
100
|
- lib/fetcheable_on_api/sortable.rb
|
101
101
|
- lib/fetcheable_on_api/version.rb
|
102
102
|
- lib/generators/fetcheable_on_api/install_generator.rb
|
@@ -1,55 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module FetcheableOnApi
|
4
|
-
# Application of a pagination on a collection
|
5
|
-
module Pagineable
|
6
|
-
#
|
7
|
-
# Supports
|
8
|
-
#
|
9
|
-
|
10
|
-
#
|
11
|
-
# Public class methods
|
12
|
-
#
|
13
|
-
|
14
|
-
#
|
15
|
-
# Public instance methods
|
16
|
-
#
|
17
|
-
|
18
|
-
#
|
19
|
-
# Protected instance methods
|
20
|
-
#
|
21
|
-
protected
|
22
|
-
|
23
|
-
def apply_pagination(collection)
|
24
|
-
return collection if params[:page].blank?
|
25
|
-
|
26
|
-
foa_valid_parameters!(:page)
|
27
|
-
|
28
|
-
limit, offset, count, page = extract_pagination_informations(collection)
|
29
|
-
define_header_pagination(limit, count, page)
|
30
|
-
|
31
|
-
collection.limit(limit).offset(offset)
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def define_header_pagination(limit, count, page)
|
37
|
-
response.headers['Pagination-Current-Page'] = page
|
38
|
-
response.headers['Pagination-Per'] = limit
|
39
|
-
response.headers['Pagination-Total-Pages'] = 1 + (count / limit).ceil
|
40
|
-
response.headers['Pagination-Total-Count'] = count
|
41
|
-
end
|
42
|
-
|
43
|
-
def extract_pagination_informations(collection)
|
44
|
-
limit = params[:page].fetch(
|
45
|
-
:size, FetcheableOnApi.configuration.pagination_default_size
|
46
|
-
).to_i
|
47
|
-
|
48
|
-
page = params[:page].fetch(:number, 1).to_i
|
49
|
-
offset = (page - 1) * limit
|
50
|
-
count = collection.except(:offset, :limit, :order).count
|
51
|
-
|
52
|
-
[limit, offset, count, page]
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|