yap 1.4.0 → 1.4.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 +2 -0
- data/lib/string_infinity.rb +2 -2
- data/lib/yap.rb +6 -75
- data/lib/yap/active_record/relation.rb +4 -4
- data/lib/yap/column_mapper.rb +9 -7
- data/lib/yap/exceptions.rb +1 -1
- data/lib/yap/extended_range.rb +11 -12
- data/lib/yap/filter.rb +34 -40
- data/lib/yap/filter_column.rb +35 -0
- data/lib/yap/filter_value.rb +67 -0
- data/lib/yap/filterable.rb +3 -16
- data/lib/yap/params_extractor.rb +102 -0
- data/lib/yap/version.rb +1 -1
- metadata +33 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04100f8b32c43f3281e414e58d2ac06bc736351f
|
4
|
+
data.tar.gz: 8242bbd5e3b635a25feb3d69264a057d491bffda
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 276f3729be6894e0ce980a4625d3f48f7b4f03730c1a89cc2468441b08c85aba33abb5aa213f2a7e2d92c08a01cb5fb8d6275af2dc65570943e67b806d3d15d8
|
7
|
+
data.tar.gz: a3424e43274c8bc5c27c6b3ebe11a5a09576a00b07685fadd6c54b64fa9234f9a0f45a9b51ea03121dbeb5180557b6c76bad8b2c54a0f613cf19ee9056467d46
|
data/README.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
[![Build Status](https://travis-ci.org/1and1/yap.svg?branch=master)](https://travis-ci.org/1and1/yap) [![Test Coverage](https://codeclimate.com/github/1and1/yap/badges/coverage.svg)](https://codeclimate.com/github/1and1/yap/coverage) [![Code Climate](https://codeclimate.com/github/1and1/yap/badges/gpa.svg)](https://codeclimate.com/github/1and1/yap)
|
2
|
+
|
1
3
|
Yet another paginator for Ruby on Rails, which adds a `paginate` scope to your ActiveRecords.
|
2
4
|
|
3
5
|
## Setup
|
data/lib/string_infinity.rb
CHANGED
data/lib/yap.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'active_support/concern'
|
2
2
|
require 'yap/active_record/relation'
|
3
|
-
require 'yap/
|
3
|
+
require 'yap/params_extractor'
|
4
4
|
require 'yap/filterable'
|
5
5
|
require 'yap/exceptions'
|
6
6
|
require 'string_infinity'
|
@@ -28,7 +28,7 @@ module Yap
|
|
28
28
|
include Filterable
|
29
29
|
|
30
30
|
DEFAULTS = Struct.new(:page, :per_page, :hard_limit, :sort, :direction, :disable_warnings)
|
31
|
-
|
31
|
+
.new(1, 10, nil, :id, :asc, false)
|
32
32
|
|
33
33
|
def self.configure
|
34
34
|
raise ArgumentError, 'No block given.' unless block_given?
|
@@ -40,85 +40,16 @@ module Yap
|
|
40
40
|
end
|
41
41
|
|
42
42
|
included do
|
43
|
-
extend
|
43
|
+
extend ParamsExtractor
|
44
44
|
|
45
45
|
##
|
46
46
|
# The paginate scope takes a hash as parameter. All options are optional and can be combined arbitrarily.
|
47
47
|
#
|
48
|
-
# @param [Hash] params The parameters used for pagination (:page, :per_page, :sort, :direction)
|
48
|
+
# @param [Hash] params The parameters used for pagination (:page, :per_page, :sort, :direction, :filter)
|
49
49
|
#
|
50
|
-
scope :paginate,
|
50
|
+
scope :paginate, lambda { |params = {}|
|
51
51
|
page, per_page, order_by = extract_pagination_params(params)
|
52
|
-
filter(params[:filter]).limit(per_page).offset((page-1)*per_page).order(order_by)
|
52
|
+
filter(params[:filter]).limit(per_page).offset((page - 1) * per_page).order(order_by)
|
53
53
|
}
|
54
|
-
|
55
|
-
private
|
56
|
-
|
57
|
-
def self.extract_pagination_params(params)
|
58
|
-
page = extract_number(params[:page], DEFAULTS.page)
|
59
|
-
per_page = extract_number(params[:per_page], DEFAULTS.per_page)
|
60
|
-
if DEFAULTS.hard_limit && per_page > DEFAULTS.hard_limit
|
61
|
-
raise PaginationError.new("Not more than #{DEFAULTS.hard_limit} items per page accepted.")
|
62
|
-
end
|
63
|
-
sort = extract_order(params[:sort], params[:direction])
|
64
|
-
|
65
|
-
return page, per_page, sort
|
66
|
-
end
|
67
|
-
|
68
|
-
def self.extract_number(number, default)
|
69
|
-
number ||= default
|
70
|
-
begin
|
71
|
-
number = Integer(number)
|
72
|
-
rescue
|
73
|
-
raise PaginationError.new("'#{number}' is not a valid number.")
|
74
|
-
end
|
75
|
-
|
76
|
-
raise PaginationError.new('Only positive numbers are accepted.') unless number > 0
|
77
|
-
number
|
78
|
-
end
|
79
|
-
|
80
|
-
def self.extract_order(sort, direction)
|
81
|
-
sort = sort.split(',') if sort.is_a?(String) && sort =~ /,/
|
82
|
-
direction = direction.split(',') if direction.is_a?(String) && direction =~ /,/
|
83
|
-
|
84
|
-
case sort
|
85
|
-
when Array
|
86
|
-
order = []
|
87
|
-
direction = Array.wrap direction
|
88
|
-
sort.each_with_index do |s, i|
|
89
|
-
order << build_order_by(s, direction[i] || DEFAULTS.direction)
|
90
|
-
end
|
91
|
-
|
92
|
-
order
|
93
|
-
when Hash
|
94
|
-
sort.map do |s, d|
|
95
|
-
build_order_by(s, d)
|
96
|
-
end
|
97
|
-
else
|
98
|
-
build_order_by sort, direction
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
def self.build_order_by(sort, direction)
|
103
|
-
sort = extract_column(sort)
|
104
|
-
direction = extract_direction(direction)
|
105
|
-
|
106
|
-
(sort =~ /\./ ? "#{sort} #{direction}" : { sort => direction })
|
107
|
-
end
|
108
|
-
private_class_method :build_order_by
|
109
|
-
|
110
|
-
def self.extract_column(sort)
|
111
|
-
sort ||= DEFAULTS.sort
|
112
|
-
column = map_column(sort.to_s.downcase)
|
113
|
-
raise PaginationError.new("Cannot sort by '#{sort}'.") unless column
|
114
|
-
column
|
115
|
-
end
|
116
|
-
|
117
|
-
def self.extract_direction(direction)
|
118
|
-
direction ||= DEFAULTS.direction
|
119
|
-
dir = (direction).to_sym.downcase
|
120
|
-
raise PaginationError.new("'#{direction}' is not a valid direction. Use 'asc' or 'desc'.") unless [:asc, :desc].include? dir
|
121
|
-
dir
|
122
|
-
end
|
123
54
|
end
|
124
55
|
end
|
@@ -20,7 +20,7 @@ module ActiveRecord
|
|
20
20
|
# @return [Integer] Total number of results
|
21
21
|
#
|
22
22
|
def total
|
23
|
-
@total ||= without_pagination
|
23
|
+
@total ||= without_pagination(&:count)
|
24
24
|
end
|
25
25
|
|
26
26
|
##
|
@@ -42,8 +42,8 @@ module ActiveRecord
|
|
42
42
|
# @return [Hash] Values defining the range of the current page.
|
43
43
|
#
|
44
44
|
def range(include_total = false)
|
45
|
-
from = offset_value+1
|
46
|
-
to = offset_value+limit_value
|
45
|
+
from = offset_value + 1
|
46
|
+
to = offset_value + limit_value
|
47
47
|
to = total if total < to && include_total
|
48
48
|
|
49
49
|
range = { from: from, to: to }
|
@@ -52,4 +52,4 @@ module ActiveRecord
|
|
52
52
|
range.merge(total: total)
|
53
53
|
end
|
54
54
|
end
|
55
|
-
end
|
55
|
+
end
|
data/lib/yap/column_mapper.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
module ColumnMapper
|
2
|
-
private
|
3
|
-
|
4
2
|
def map_column(name)
|
5
|
-
column_names.include?(name)
|
3
|
+
actual_column = name if column_names.include?(name)
|
4
|
+
|
5
|
+
column_alias = if respond_to? :map_name_to_column
|
6
6
|
map_name_to_column(name)
|
7
|
-
|
8
|
-
warn "#{self.name} does not implement map_name_to_column. If you do not need column mapping set
|
9
|
-
|
7
|
+
elsif actual_column.nil? && !Yap::DEFAULTS.disable_warnings
|
8
|
+
warn "#{self.name} does not implement map_name_to_column. If you do not need column mapping set " \
|
9
|
+
'disable_warnings=true'
|
10
10
|
end
|
11
|
+
|
12
|
+
column_alias || actual_column
|
11
13
|
end
|
12
|
-
end
|
14
|
+
end
|
data/lib/yap/exceptions.rb
CHANGED
data/lib/yap/extended_range.rb
CHANGED
@@ -1,24 +1,23 @@
|
|
1
1
|
module Yap
|
2
|
+
##
|
3
|
+
# Extends Range by StringInfinity.
|
4
|
+
#
|
2
5
|
class ExtendedRange < Range
|
3
6
|
def begin
|
4
|
-
|
7
|
+
handle_infinity super
|
5
8
|
end
|
6
9
|
|
7
10
|
def end
|
8
|
-
|
11
|
+
handle_infinity super
|
9
12
|
end
|
10
13
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
-Float::INFINITY
|
17
|
-
else
|
18
|
-
raise ArgumentError, "Invalid value for StringInfinity."
|
19
|
-
end
|
14
|
+
def handle_infinity(value)
|
15
|
+
return value unless value.is_a? StringInfinity
|
16
|
+
|
17
|
+
if value.is_a?(StringInfinityNegative)
|
18
|
+
-Float::INFINITY
|
20
19
|
else
|
21
|
-
|
20
|
+
Float::INFINITY
|
22
21
|
end
|
23
22
|
end
|
24
23
|
end
|
data/lib/yap/filter.rb
CHANGED
@@ -1,58 +1,52 @@
|
|
1
|
-
require 'yap/
|
1
|
+
require 'yap/filter_column'
|
2
2
|
|
3
3
|
module Yap
|
4
|
-
class Filter
|
4
|
+
class Filter
|
5
5
|
def initialize
|
6
|
-
|
7
|
-
|
6
|
+
@failed = []
|
7
|
+
@columns = []
|
8
8
|
end
|
9
9
|
|
10
|
-
def parse!(
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
match = :not
|
15
|
-
value = $1
|
16
|
-
else
|
17
|
-
match = :where
|
18
|
-
end
|
10
|
+
def parse!(model, params)
|
11
|
+
params.each do |attribute, values|
|
12
|
+
parse_arrtibute(model, attribute, values)
|
13
|
+
end
|
19
14
|
|
20
|
-
|
21
|
-
|
22
|
-
match, value = handle_comparison_operators(match, column, $1.to_sym, $2)
|
23
|
-
when /(.+)\.{3}(.+)/
|
24
|
-
value = $1...$2
|
25
|
-
when /(.+)\.{2}(.+)/
|
26
|
-
value = $1..$2
|
27
|
-
else
|
28
|
-
# Convert null to ruby nil to use 'IS NULL' in SQL.
|
29
|
-
value = value.downcase == 'null' ? nil : value
|
30
|
-
end
|
15
|
+
raise FilterError, "Cannot filter by: #{@failed.join(', ')}" unless @failed.empty?
|
16
|
+
end
|
31
17
|
|
32
|
-
|
33
|
-
|
18
|
+
def where
|
19
|
+
extract_filters(:where)
|
20
|
+
end
|
34
21
|
|
35
|
-
|
36
|
-
|
22
|
+
def not
|
23
|
+
extract_filters(:not)
|
37
24
|
end
|
38
25
|
|
39
26
|
private
|
40
27
|
|
41
|
-
def
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
return match, ExtendedRange.new(value, String::INFINITY)
|
28
|
+
def extract_filters(condition)
|
29
|
+
@columns.inject({}) do |filter, column|
|
30
|
+
values = column.send(condition)
|
31
|
+
|
32
|
+
if values.empty?
|
33
|
+
filter
|
34
|
+
else
|
35
|
+
filter.merge(column.name => values.size == 1 ? values.first : values)
|
36
|
+
end
|
51
37
|
end
|
52
38
|
end
|
53
39
|
|
54
|
-
def
|
55
|
-
|
40
|
+
def parse_arrtibute(model, attribute, values)
|
41
|
+
column = model.map_column(attribute.to_s.downcase)
|
42
|
+
if column.nil?
|
43
|
+
@failed << attribute
|
44
|
+
return
|
45
|
+
end
|
46
|
+
|
47
|
+
filter_column = FilterColumn.new(column)
|
48
|
+
filter_column.parse_values(values)
|
49
|
+
@columns << filter_column
|
56
50
|
end
|
57
51
|
end
|
58
52
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'yap/filter_value'
|
2
|
+
|
3
|
+
module Yap
|
4
|
+
##
|
5
|
+
# Multiple filter for a column can be separated by comma (,).
|
6
|
+
#
|
7
|
+
class FilterColumn
|
8
|
+
attr_reader :name
|
9
|
+
|
10
|
+
def initialize(name)
|
11
|
+
@name = name
|
12
|
+
@values = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def parse_values(values)
|
16
|
+
values.to_s.split(',').each do |value|
|
17
|
+
filter_value = FilterValue.new
|
18
|
+
filter_value.parse_value(value)
|
19
|
+
@values << filter_value
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def where
|
24
|
+
@values.select do |v|
|
25
|
+
v.condition == :where
|
26
|
+
end.map(&:value)
|
27
|
+
end
|
28
|
+
|
29
|
+
def not
|
30
|
+
@values.select do |v|
|
31
|
+
v.condition == :not
|
32
|
+
end.map(&:value)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'yap/extended_range'
|
2
|
+
|
3
|
+
module Yap
|
4
|
+
##
|
5
|
+
# Filter values can have the following formats:
|
6
|
+
#
|
7
|
+
# * Integer - e.g. 100
|
8
|
+
# * String - e.g. text
|
9
|
+
# * Comparisons - e.g. >10, <=B
|
10
|
+
# * Dates - e.g. 1970-01-01 (depends on the database backend)
|
11
|
+
# * Ranges - e.g. 1...2, Jones..Smith
|
12
|
+
# * NULL - e.g. NULL, null, Null
|
13
|
+
# * Negation - e.g. !value, !1..10
|
14
|
+
#
|
15
|
+
class FilterValue
|
16
|
+
OPERATOR_INVERSION_MAP = { :< => :>=, :> => :<= }.freeze
|
17
|
+
|
18
|
+
attr_reader :condition, :value
|
19
|
+
|
20
|
+
def parse_value(value)
|
21
|
+
value = handle_negation(value)
|
22
|
+
|
23
|
+
@value = case value
|
24
|
+
when /([<>]=?)(.+)/
|
25
|
+
handle_comparison_operators($1.to_sym, $2)
|
26
|
+
when /(.+)(\.{2,3})(.+)/
|
27
|
+
Range.new $1, $3, $2 == '...'
|
28
|
+
else
|
29
|
+
handle_null(value)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def handle_negation(value)
|
36
|
+
if value =~ /^!(.+)$/
|
37
|
+
@condition = :not
|
38
|
+
value = $1
|
39
|
+
else
|
40
|
+
@condition = :where
|
41
|
+
end
|
42
|
+
|
43
|
+
value
|
44
|
+
end
|
45
|
+
|
46
|
+
def handle_comparison_operators(operator, value)
|
47
|
+
case operator
|
48
|
+
when :<, :> then invert_comparison_operator(operator, value)
|
49
|
+
when :<= then ExtendedRange.new(-String::INFINITY, value)
|
50
|
+
when :>= then ExtendedRange.new(value, String::INFINITY)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def invert_comparison_operator(operator, value)
|
55
|
+
toggle_condition!
|
56
|
+
handle_comparison_operators(OPERATOR_INVERSION_MAP[operator], value)
|
57
|
+
end
|
58
|
+
|
59
|
+
def toggle_condition!
|
60
|
+
@condition = @condition == :where ? :not : :where
|
61
|
+
end
|
62
|
+
|
63
|
+
def handle_null(value)
|
64
|
+
value.casecmp('null').zero? ? nil : value
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/yap/filterable.rb
CHANGED
@@ -32,31 +32,18 @@ module Yap
|
|
32
32
|
#
|
33
33
|
# @param [Hash] Attribute/value pairs to filter ( { 'gender' => 'f' } )
|
34
34
|
#
|
35
|
-
scope :filter,
|
35
|
+
scope :filter, lambda { |params = nil|
|
36
36
|
if params.blank?
|
37
37
|
all
|
38
38
|
else
|
39
39
|
filter = extract_filter_params(params)
|
40
|
-
where(filter
|
40
|
+
where(filter.where).where.not(filter.not)
|
41
41
|
end
|
42
42
|
}
|
43
43
|
|
44
|
-
private
|
45
|
-
|
46
44
|
def self.extract_filter_params(params)
|
47
45
|
filter = Filter.new
|
48
|
-
|
49
|
-
failed = []
|
50
|
-
params.each do |key, values|
|
51
|
-
column = map_column(key.to_s.downcase)
|
52
|
-
if column
|
53
|
-
filter.parse!(column, values)
|
54
|
-
else
|
55
|
-
failed << key
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
raise FilterError.new('Cannot filter by: ' + failed.join(', ')) unless failed.empty?
|
46
|
+
filter.parse!(self, params)
|
60
47
|
|
61
48
|
filter
|
62
49
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'yap/column_mapper'
|
2
|
+
|
3
|
+
module Yap
|
4
|
+
##
|
5
|
+
# Methods for extracting valid pagination parameters from rails params.
|
6
|
+
#
|
7
|
+
module ParamsExtractor
|
8
|
+
def extract_pagination_params(params)
|
9
|
+
page = extract_page(params)
|
10
|
+
per_page = extract_per_page(params)
|
11
|
+
sort = extract_order(params)
|
12
|
+
|
13
|
+
[page, per_page, sort]
|
14
|
+
end
|
15
|
+
|
16
|
+
def extract_page(params)
|
17
|
+
extract_number(params[:page], DEFAULTS.page)
|
18
|
+
end
|
19
|
+
|
20
|
+
def extract_per_page(params)
|
21
|
+
per_page = extract_number(params[:per_page], DEFAULTS.per_page)
|
22
|
+
|
23
|
+
if DEFAULTS.hard_limit && per_page > DEFAULTS.hard_limit
|
24
|
+
raise PaginationError, "Not more than #{DEFAULTS.hard_limit} items per page accepted."
|
25
|
+
end
|
26
|
+
|
27
|
+
per_page
|
28
|
+
end
|
29
|
+
|
30
|
+
def extract_number(number, default)
|
31
|
+
number ||= default
|
32
|
+
begin
|
33
|
+
number = Integer(number)
|
34
|
+
rescue ArgumentError
|
35
|
+
raise PaginationError, "'#{number}' is not a valid number."
|
36
|
+
end
|
37
|
+
|
38
|
+
raise PaginationError, 'Only positive numbers are accepted.' unless number > 0
|
39
|
+
number
|
40
|
+
end
|
41
|
+
|
42
|
+
def extract_order(params)
|
43
|
+
sort, direction = params.values_at(:sort, :direction)
|
44
|
+
|
45
|
+
case sort
|
46
|
+
when Array, String
|
47
|
+
build_order_from_array(sort, direction)
|
48
|
+
when Hash
|
49
|
+
build_order_from_hash(sort)
|
50
|
+
else # nil or symbol
|
51
|
+
build_order sort, direction
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def build_order_from_array(sort, direction = [])
|
56
|
+
sort = convert_to_array(sort)
|
57
|
+
direction = convert_to_array(direction)
|
58
|
+
order = []
|
59
|
+
sort.each_with_index do |s, i|
|
60
|
+
order << build_order(s, direction[i] || DEFAULTS.direction)
|
61
|
+
end
|
62
|
+
|
63
|
+
order
|
64
|
+
end
|
65
|
+
|
66
|
+
def convert_to_array(object)
|
67
|
+
object = object.split(',') if object.is_a?(String)
|
68
|
+
|
69
|
+
Array.wrap(object)
|
70
|
+
end
|
71
|
+
|
72
|
+
def build_order_from_hash(sort)
|
73
|
+
sort.map do |s, d|
|
74
|
+
build_order(s, d)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def build_order(sort, direction)
|
79
|
+
sort = extract_column(sort || DEFAULTS.sort)
|
80
|
+
direction = extract_direction(direction)
|
81
|
+
|
82
|
+
(sort =~ /\./ ? "#{sort} #{direction}" : { sort => direction })
|
83
|
+
end
|
84
|
+
|
85
|
+
def extract_column(sort)
|
86
|
+
column = map_column(sort.to_s.downcase)
|
87
|
+
raise PaginationError, "Cannot sort by '#{sort}'." unless column
|
88
|
+
|
89
|
+
column
|
90
|
+
end
|
91
|
+
|
92
|
+
def extract_direction(direction)
|
93
|
+
direction ||= DEFAULTS.direction
|
94
|
+
dir = direction.to_sym.downcase
|
95
|
+
unless [:asc, :desc].include? dir
|
96
|
+
raise PaginationError, "'#{direction}' is not a valid direction. Use 'asc' or 'desc'."
|
97
|
+
end
|
98
|
+
|
99
|
+
dir
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
data/lib/yap/version.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Finn Glöe
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-02-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.2'
|
20
|
+
- - "<"
|
18
21
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
22
|
+
version: '6'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '4.2'
|
30
|
+
- - "<"
|
25
31
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
32
|
+
version: '6'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: sqlite3
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,7 +44,21 @@ dependencies:
|
|
38
44
|
- - "~>"
|
39
45
|
- !ruby/object:Gem::Version
|
40
46
|
version: '1.3'
|
41
|
-
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '11.1'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '11.1'
|
61
|
+
description: Yet another paginator for Ruby on Rails adding pagination and filtering
|
42
62
|
interface to ActiveRecords.
|
43
63
|
email: finn.gloee@1und1.de
|
44
64
|
executables: []
|
@@ -54,7 +74,10 @@ files:
|
|
54
74
|
- lib/yap/exceptions.rb
|
55
75
|
- lib/yap/extended_range.rb
|
56
76
|
- lib/yap/filter.rb
|
77
|
+
- lib/yap/filter_column.rb
|
78
|
+
- lib/yap/filter_value.rb
|
57
79
|
- lib/yap/filterable.rb
|
80
|
+
- lib/yap/params_extractor.rb
|
58
81
|
- lib/yap/version.rb
|
59
82
|
homepage: https://github.com/1and1/yap
|
60
83
|
licenses:
|
@@ -66,9 +89,9 @@ require_paths:
|
|
66
89
|
- lib
|
67
90
|
required_ruby_version: !ruby/object:Gem::Requirement
|
68
91
|
requirements:
|
69
|
-
- - "
|
92
|
+
- - ">="
|
70
93
|
- !ruby/object:Gem::Version
|
71
|
-
version:
|
94
|
+
version: 1.9.3
|
72
95
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
96
|
requirements:
|
74
97
|
- - ">="
|
@@ -76,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
76
99
|
version: '0'
|
77
100
|
requirements: []
|
78
101
|
rubyforge_project:
|
79
|
-
rubygems_version: 2.
|
102
|
+
rubygems_version: 2.6.10
|
80
103
|
signing_key:
|
81
104
|
specification_version: 4
|
82
105
|
summary: Yet another paginator for Ruby on Rails
|