activerecord-filter 1.0.0.alpha
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 +7 -0
- data/README.md +2 -0
- data/ext/active_record/base.rb +251 -0
- data/ext/active_record/query_methods.rb +27 -0
- data/ext/active_record/unkown_filter_error.rb +9 -0
- data/ext/arel/attributes/array.rb +5 -0
- data/ext/arel/nodes/contains.rb +6 -0
- data/ext/arel/nodes/overlaps.rb +6 -0
- data/ext/arel/visitors/postgresql.rb +30 -0
- data/lib/active_record/filter.rb +9 -0
- data/lib/active_record/filter/version.rb +5 -0
- metadata +199 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bf2f420a770b315c9c5447527d2f54b0f3345e3f
|
4
|
+
data.tar.gz: 1bf8eb361be7b60ffddf0ca081a88dd8cb0b485c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: acdd1fdab608afd088bdc97a71f1f2cfa5cc22066790ec32d1edba9007264ef5e2307a48bce8b157c2283c1feffc527e6a531928219e0cb9dc2c8790b8d616f4
|
7
|
+
data.tar.gz: 908e00ea9062f1157be09479244c4ec401df5d836017e3a6acba87451649c9438171ca3f1c7ca06cadc015c5d8910860627ee607b89c7ce73c9d4cea0777559e
|
data/README.md
ADDED
@@ -0,0 +1,251 @@
|
|
1
|
+
class ActiveRecord::Base
|
2
|
+
class << self
|
3
|
+
|
4
|
+
def inherited_with_filter(subclass)
|
5
|
+
inherited_without_filter(subclass)
|
6
|
+
subclass.instance_variable_set('@filters', HashWithIndifferentAccess.new)
|
7
|
+
end
|
8
|
+
alias_method_chain :inherited, :filter
|
9
|
+
|
10
|
+
def filter_on(name, lambda)
|
11
|
+
@filters[name] = lambda
|
12
|
+
end
|
13
|
+
|
14
|
+
def filter(filters, options={})
|
15
|
+
resource = all
|
16
|
+
return resource unless filters
|
17
|
+
|
18
|
+
if filters.is_a? Hash
|
19
|
+
filters.each do |key, value|
|
20
|
+
if @filters[key]
|
21
|
+
#TODO add test for this... not sure how rails does this lambda call,
|
22
|
+
# do they run it in a context for merge?
|
23
|
+
resource = resource.merge( @filters[key].call(value) )
|
24
|
+
else
|
25
|
+
resource = resource.filter_for(key, value, options)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
elsif filters.is_a?(Array) || filters.is_a?(Integer)
|
29
|
+
resource = resource.filter_for(:id, filters, options)
|
30
|
+
end
|
31
|
+
|
32
|
+
resource
|
33
|
+
end
|
34
|
+
|
35
|
+
def filter_for(key, value, options={})
|
36
|
+
column = columns_hash[key.to_s]
|
37
|
+
if column && column.array
|
38
|
+
all.filter_for_array(key, value, options)
|
39
|
+
elsif column
|
40
|
+
all.send("filter_for_#{column.type}", key, value, options)
|
41
|
+
else
|
42
|
+
if relation = reflect_on_association(key)
|
43
|
+
self.send("filter_for_#{relation.macro}", relation, value)
|
44
|
+
else
|
45
|
+
raise ActiveRecord::UnkownFilterError.new(self, key)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
{
|
51
|
+
filter_for_geometry: :itself,
|
52
|
+
filter_for_datetime: :to_datetime,
|
53
|
+
filter_for_integer: :to_i,
|
54
|
+
filter_for_text: :itself,
|
55
|
+
filter_for_boolean: :itself,
|
56
|
+
filter_for_string: :itself,
|
57
|
+
filter_for_decimal: :to_f
|
58
|
+
}.each_pair do |method_name, send_method|
|
59
|
+
define_method(method_name) do |column, value, options={}|
|
60
|
+
table = options[:table_alias] ? arel_table.alias(options[:table_alias]) : arel_table
|
61
|
+
|
62
|
+
case value
|
63
|
+
when Hash
|
64
|
+
resource = all
|
65
|
+
value.each_pair do |key, value|
|
66
|
+
converted_value = value.try(:send, send_method)
|
67
|
+
resource = case key.to_sym
|
68
|
+
when :greater_than, :gt
|
69
|
+
resource.where(table[column].gt(converted_value))
|
70
|
+
when :less_than, :lt
|
71
|
+
resource.where(table[column].lt(converted_value))
|
72
|
+
when :greater_than_or_equal_to, :gteq, :gte
|
73
|
+
resource.where(table[column].gteq(converted_value))
|
74
|
+
when :less_than_or_equal_to, :lteq, :lte
|
75
|
+
resource.where(table[column].lteq(converted_value))
|
76
|
+
when :not
|
77
|
+
resource.where(table[column].not_eq(converted_value))
|
78
|
+
when :not_in
|
79
|
+
resource.where(table[column].not_in(value).or(table[column].eq(nil)))
|
80
|
+
when :intersects
|
81
|
+
# geometry_value = if value.is_a?(Hash) # GeoJSON
|
82
|
+
# Arel::Nodes::NamedFunction.new('ST_GeomFromGeoJSON', [JSON.generate(value)])
|
83
|
+
# elsif # EWKB
|
84
|
+
# elsif # WKB
|
85
|
+
# elsif # EWKT
|
86
|
+
# elsif # WKT
|
87
|
+
# end
|
88
|
+
|
89
|
+
# TODO us above if to determin if SRID sent
|
90
|
+
geometry_value = if value.is_a?(Hash)
|
91
|
+
Arel::Nodes::NamedFunction.new('ST_SetSRID', [Arel::Nodes::NamedFunction.new('ST_GeomFromGeoJSON', [Arel::Nodes.build_quoted(JSON.generate(value))]), 4326])
|
92
|
+
elsif value[0,1] == "\x00" || value[0,1] == "\x01" || value[0,4] =~ /[0-9a-fA-F]{4}/
|
93
|
+
Arel::Nodes::NamedFunction.new('ST_SetSRID', [Arel::Nodes::NamedFunction.new('ST_GeomFromEWKB', [Arel::Nodes.build_quoted(value)]), 4326])
|
94
|
+
else
|
95
|
+
Arel::Nodes::NamedFunction.new('ST_SetSRID', [Arel::Nodes::NamedFunction.new('ST_GeomFromText', [Arel::Nodes.build_quoted(value)]), 4326])
|
96
|
+
end
|
97
|
+
|
98
|
+
resource.where(Arel::Nodes::NamedFunction.new('ST_Intersects', [table[column], geometry_value]))
|
99
|
+
else
|
100
|
+
raise "Not Supported: #{key.to_sym}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
resource
|
104
|
+
when Array
|
105
|
+
where(table[column].in(value.map { |x| x.send(send_method) }))
|
106
|
+
when true, 'true'
|
107
|
+
case method_name # columns_hash[column.to_s].try(:type)
|
108
|
+
when :filter_for_boolean then where(table[column].eq(value.try(:send, send_method)))
|
109
|
+
else where(table[column].not_eq(nil))
|
110
|
+
end
|
111
|
+
when false, 'false'
|
112
|
+
case method_name # columns_hash[column.to_s].try(:type)
|
113
|
+
when :filter_for_boolean then where(table[column].eq(value.try(:send, send_method)))
|
114
|
+
else where(table[column].eq(nil))
|
115
|
+
end
|
116
|
+
# when ''
|
117
|
+
# # TODO support nil. Currently rails params encode nil as empty strings,
|
118
|
+
# # and we can't tell which is desired, so do both
|
119
|
+
# where(table[column].eq(value).or(table[column].eq(nil)))
|
120
|
+
else
|
121
|
+
where(table[column].eq(value.try(:send, send_method)))
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def filter_for_jsonb(column, value, options = {})
|
127
|
+
table = options[:table_alias] ? arel_table.alias(options[:table_alias]) : arel_table
|
128
|
+
|
129
|
+
case value
|
130
|
+
when true, 'true'
|
131
|
+
where(table[column].not_eq(nil))
|
132
|
+
when false, 'false'
|
133
|
+
where(table[column].eq(nil))
|
134
|
+
when nil
|
135
|
+
where(table[column].eq(nil))
|
136
|
+
else
|
137
|
+
puts value.inspect
|
138
|
+
raise 'Not supported'
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def filter_for_array(column, value, options={})
|
143
|
+
table = options[:table_alias] ? arel_table.alias(options[:table_alias]) : arel_table
|
144
|
+
|
145
|
+
case value
|
146
|
+
when Array
|
147
|
+
where(Arel::Nodes::Overlaps.new(table[column], Arel::Attributes::Array.new(value)))
|
148
|
+
else
|
149
|
+
any_column = Arel::Nodes::NamedFunction.new('ANY', [table[column]])
|
150
|
+
predicate = Arel::Nodes::Equality.new(Arel::Nodes.build_quoted(value), any_column)
|
151
|
+
where(predicate)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def filter_for_has_and_belongs_to_many(relation, value)
|
156
|
+
resource = all
|
157
|
+
|
158
|
+
options = {}
|
159
|
+
if resource.klass == relation.klass
|
160
|
+
options[:table_alias] = "#{relation.name}_#{relation.klass.table_name}"
|
161
|
+
end
|
162
|
+
|
163
|
+
case value
|
164
|
+
when Hash
|
165
|
+
resource = resource.joins(relation.name) if !resource.references?(relation.name)
|
166
|
+
resource = resource.merge(relation.klass.filter(value, options))
|
167
|
+
when Integer
|
168
|
+
resource = resource.joins(relation.name) if !resource.references?(relation.name)
|
169
|
+
resource = resource.merge(relation.klass.filter(value, options))
|
170
|
+
when Array
|
171
|
+
resource = resource.joins(relation.name) if !resource.references?(relation.name)
|
172
|
+
resource = resource.merge(relation.klass.filter(value, options))
|
173
|
+
else
|
174
|
+
raise 'Not supported'
|
175
|
+
end
|
176
|
+
|
177
|
+
resource
|
178
|
+
end
|
179
|
+
|
180
|
+
def filter_for_has_many(relation, value)
|
181
|
+
resource = all
|
182
|
+
|
183
|
+
case value
|
184
|
+
when Hash
|
185
|
+
if relation.options[:through]
|
186
|
+
resource = resource.joins(relation.options[:through] => relation.source_reflection_name)
|
187
|
+
else
|
188
|
+
resource = resource.joins(relation.name) # if !resource.joined?(relation.name)
|
189
|
+
end
|
190
|
+
resource = resource.merge(relation.klass.filter(value))
|
191
|
+
when Array, Integer
|
192
|
+
resource = filter_for_has_many(relation, {:id => value})
|
193
|
+
when true, 'true'
|
194
|
+
counter_cache_column_name = relation.counter_cache_column || "#{relation.plural_name}_count"
|
195
|
+
if resource.column_names.include?(counter_cache_column_name)
|
196
|
+
resource = resource.where(resource.arel_table[counter_cache_column_name.to_sym].gt(0))
|
197
|
+
else
|
198
|
+
raise 'Not supported'
|
199
|
+
end
|
200
|
+
when false, 'false'
|
201
|
+
# TODO if the has_many relationship has counter_cache true can just use counter_cache_column method
|
202
|
+
counter_cache_column_name = relation.counter_cache_column || "#{relation.plural_name}_count"
|
203
|
+
if resource.column_names.include?(counter_cache_column_name)
|
204
|
+
resource = resource.where(resource.arel_table[counter_cache_column_name.to_sym].eq(0))
|
205
|
+
else
|
206
|
+
raise 'Not supported'
|
207
|
+
end
|
208
|
+
else
|
209
|
+
raise 'Not supported'
|
210
|
+
end
|
211
|
+
|
212
|
+
resource
|
213
|
+
end
|
214
|
+
alias_method :filter_for_has_one, :filter_for_has_many
|
215
|
+
|
216
|
+
def filter_for_belongs_to(relation, value)
|
217
|
+
resource = all
|
218
|
+
|
219
|
+
case value
|
220
|
+
when Array, Integer, NilClass
|
221
|
+
resource = resource.where(:"#{relation.foreign_key}" => value)
|
222
|
+
when true, 'true'
|
223
|
+
resource = resource.where(resource.arel_table[:"#{relation.foreign_key}"].not_eq(nil))
|
224
|
+
when false, 'false'
|
225
|
+
resource = resource.where(resource.arel_table[:"#{relation.foreign_key}"].eq(nil))
|
226
|
+
when Hash
|
227
|
+
if relation.polymorphic?
|
228
|
+
raise 'no :as' if !value[:as]
|
229
|
+
klass = value.delete(:as).classify.constantize
|
230
|
+
t1 = resource.arel_table
|
231
|
+
t2 = klass.arel_table
|
232
|
+
resource = resource.joins(t1.join(t2).on(
|
233
|
+
t2[:id].eq(t1["#{relation.name}_id"]).and(t1["#{relation.name}_type"].eq(klass.name))
|
234
|
+
).join_sources.first)
|
235
|
+
resource = resource.merge(klass.filter(value))
|
236
|
+
else
|
237
|
+
resource = resource.joins(relation.name) # if !resource.references?(relation.name)
|
238
|
+
resource = resource.merge(relation.klass.filter(value))
|
239
|
+
end
|
240
|
+
else
|
241
|
+
if value.is_a?(String) && value =~ /\A\d+\Z/
|
242
|
+
resource = resource.where(:"#{relation.foreign_key}" => value.to_i)
|
243
|
+
else
|
244
|
+
raise 'Not supported'
|
245
|
+
end
|
246
|
+
end
|
247
|
+
resource
|
248
|
+
end
|
249
|
+
|
250
|
+
end
|
251
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module ActiveRecord::QueryMethods
|
2
|
+
|
3
|
+
# # TODO: testme and rename to joins?
|
4
|
+
# def joined?(assoc)
|
5
|
+
# joined_assocs = joins_values.map{ |i| i.is_a?(Hash) ? i.keys : i.to_sym }.flatten
|
6
|
+
# joined_assocs.include?(assoc)
|
7
|
+
# end
|
8
|
+
#
|
9
|
+
# # TODO: testme and rename to includes?
|
10
|
+
# def included?(assoc)
|
11
|
+
# included_assocs = includes_values.map{ |i| i.is_a?(Hash) ? i.keys : i.to_sym }.flatten
|
12
|
+
# included_assocs.include?(assoc)
|
13
|
+
# end
|
14
|
+
|
15
|
+
# TODO: testme and rename to
|
16
|
+
def references?(assoc)
|
17
|
+
references_assocs = references_values.map{ |i| i.is_a?(Hash) ? i.keys : i.to_sym }.flatten
|
18
|
+
references_assocs.include?(assoc)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
module ActiveRecord::Querying
|
24
|
+
# delegate :joined?, :to => :all
|
25
|
+
# delegate :included?, :to => :all
|
26
|
+
delegate :references?, :to => :all
|
27
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Arel
|
2
|
+
module Visitors
|
3
|
+
class PostgreSQL
|
4
|
+
private
|
5
|
+
|
6
|
+
def visit_Arel_Nodes_Contains o, collector
|
7
|
+
visit o.left, collector
|
8
|
+
collector << ' @> '
|
9
|
+
visit o.right, collector
|
10
|
+
end
|
11
|
+
|
12
|
+
def visit_Arel_Nodes_Overlaps o, collector
|
13
|
+
visit o.left, collector
|
14
|
+
collector << ' && '
|
15
|
+
visit o.right, collector
|
16
|
+
end
|
17
|
+
|
18
|
+
def visit_Arel_Attributes_Array o, collector
|
19
|
+
type = if !o.relation[0]
|
20
|
+
ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array.new(nil)
|
21
|
+
else
|
22
|
+
ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array.new("ActiveRecord::Type::#{o.relation[0].class}".constantize.new)
|
23
|
+
end
|
24
|
+
|
25
|
+
collector << quote(type.type_cast_for_database(o.relation))
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
require File.expand_path(File.join(__FILE__, '../../../ext/arel/attributes/array'))
|
4
|
+
require File.expand_path(File.join(__FILE__, '../../../ext/arel/nodes/contains'))
|
5
|
+
require File.expand_path(File.join(__FILE__, '../../../ext/arel/nodes/overlaps'))
|
6
|
+
require File.expand_path(File.join(__FILE__, '../../../ext/arel/visitors/postgresql'))
|
7
|
+
require File.expand_path(File.join(__FILE__, '../../../ext/active_record/unkown_filter_error'))
|
8
|
+
require File.expand_path(File.join(__FILE__, '../../../ext/active_record/base'))
|
9
|
+
require File.expand_path(File.join(__FILE__, '../../../ext/active_record/query_methods'))
|
metadata
ADDED
@@ -0,0 +1,199 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: activerecord-filter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0.alpha
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jon Bracy
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-07-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pg
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activerecord
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: minitest-reporters
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: sqlite3
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: factory_girl_rails
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: faker
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
description: A safe way to accept user parameters and query against your ActiveRecord
|
154
|
+
Models
|
155
|
+
email:
|
156
|
+
- jonbracy@gmail.com
|
157
|
+
executables: []
|
158
|
+
extensions: []
|
159
|
+
extra_rdoc_files:
|
160
|
+
- README.md
|
161
|
+
files:
|
162
|
+
- README.md
|
163
|
+
- ext/active_record/base.rb
|
164
|
+
- ext/active_record/query_methods.rb
|
165
|
+
- ext/active_record/unkown_filter_error.rb
|
166
|
+
- ext/arel/attributes/array.rb
|
167
|
+
- ext/arel/nodes/contains.rb
|
168
|
+
- ext/arel/nodes/overlaps.rb
|
169
|
+
- ext/arel/visitors/postgresql.rb
|
170
|
+
- lib/active_record/filter.rb
|
171
|
+
- lib/active_record/filter/version.rb
|
172
|
+
homepage: https://github.com/malomalo/activerecord-filter
|
173
|
+
licenses:
|
174
|
+
- MIT
|
175
|
+
metadata: {}
|
176
|
+
post_install_message:
|
177
|
+
rdoc_options:
|
178
|
+
- "--main"
|
179
|
+
- README.md
|
180
|
+
require_paths:
|
181
|
+
- lib
|
182
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
183
|
+
requirements:
|
184
|
+
- - ">="
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: '0'
|
187
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
188
|
+
requirements:
|
189
|
+
- - ">"
|
190
|
+
- !ruby/object:Gem::Version
|
191
|
+
version: 1.3.1
|
192
|
+
requirements: []
|
193
|
+
rubyforge_project:
|
194
|
+
rubygems_version: 2.4.5
|
195
|
+
signing_key:
|
196
|
+
specification_version: 4
|
197
|
+
summary: A safe way to accept user parameters and query against your ActiveRecord
|
198
|
+
Models
|
199
|
+
test_files: []
|