active_filter 0.0.2 → 0.0.3
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.
- data/MIT-LICENSE +1 -1
- data/lib/active_filter/base.rb +92 -39
- data/lib/active_filter/engine.rb +3 -0
- data/lib/active_filter/field.rb +93 -0
- data/lib/active_filter/version.rb +1 -1
- data/lib/active_filter.rb +1 -1
- metadata +41 -9
- data/lib/active_filter/rule.rb +0 -23
data/MIT-LICENSE
CHANGED
data/lib/active_filter/base.rb
CHANGED
@@ -1,55 +1,93 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
require "active_filter/
|
2
|
+
require "active_filter/field"
|
3
3
|
|
4
4
|
module ActiveFilter
|
5
5
|
class Base
|
6
|
-
|
7
|
-
|
6
|
+
attr_reader :fields
|
7
|
+
|
8
|
+
def initialize(scope=nil, data={})
|
9
|
+
if scope.is_a?(Hash)
|
10
|
+
@scope = nil
|
11
|
+
@data = scope
|
12
|
+
else
|
13
|
+
@scope = scope
|
14
|
+
@data = data
|
15
|
+
end
|
16
|
+
|
17
|
+
@fields = []
|
18
|
+
self.class._model.columns.each do |column|
|
19
|
+
if self.class._field_names.include?(column.name) ||
|
20
|
+
self.class._field_names.include?(column.name.to_sym)
|
21
|
+
@fields << _create_field_from_column(column)
|
22
|
+
end
|
23
|
+
end
|
8
24
|
end
|
9
25
|
|
10
26
|
private
|
11
|
-
def self.
|
12
|
-
|
13
|
-
# インスタンス変数にルールを格納
|
14
|
-
@rules ||= []
|
27
|
+
def self._field_names
|
28
|
+
@field_names ||= []
|
15
29
|
end
|
16
30
|
|
17
31
|
def self._model
|
18
|
-
# Class クラスのインスタンスである ActiveFilter::Base オブジェクトの
|
19
|
-
# インスタンス変数にモデルの型を格納
|
20
32
|
@model
|
21
33
|
end
|
22
34
|
|
23
|
-
|
24
|
-
|
25
|
-
|
35
|
+
def _create_field_from_column(column)
|
36
|
+
case column.type
|
37
|
+
when :primary_key
|
38
|
+
return Field.new(column.name)
|
39
|
+
when :string
|
40
|
+
return StringField.new(column.name)
|
41
|
+
when :text
|
42
|
+
return TextField.new(column.name)
|
43
|
+
when :integer
|
44
|
+
return IntegerField.new(column.name)
|
45
|
+
when :float
|
46
|
+
return FloatField.new(column.name)
|
47
|
+
when :decimal
|
48
|
+
return DecimalField.new(column.name)
|
49
|
+
when :datetime
|
50
|
+
return DateTimeField.new(column.name)
|
51
|
+
when :timestamp
|
52
|
+
return Field.new(column.name)
|
53
|
+
when :time
|
54
|
+
return TimeField.new(column.name)
|
55
|
+
when :date
|
56
|
+
return DateField.new(column.name)
|
57
|
+
when :binary
|
58
|
+
return Field.new(column.name)
|
59
|
+
when :boolean
|
60
|
+
return BooleanField.new(column.name)
|
61
|
+
else
|
62
|
+
raise ArgumentError.new("#{column.type} is not supported.")
|
63
|
+
end
|
26
64
|
end
|
27
65
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
# ラムダ式またはブロックのどちらか必須
|
34
|
-
raise ArgumentError, "lambda or block are required!"
|
35
|
-
end
|
66
|
+
# コンストラクタで受け取ったスコープまたは
|
67
|
+
# model.scoped を返す
|
68
|
+
def _scoped
|
69
|
+
if @scope.nil?
|
70
|
+
self.class._model.scoped
|
36
71
|
else
|
37
|
-
|
72
|
+
@scope
|
38
73
|
end
|
39
|
-
|
40
|
-
_rules << ActiveFilter::Rule.new(pattern, &callback)
|
41
74
|
end
|
42
75
|
|
43
|
-
|
44
|
-
|
45
|
-
|
76
|
+
protected
|
77
|
+
# フィルタを作成する対象のモデルを指定します。
|
78
|
+
def self.model(klass)
|
79
|
+
# Class クラスのインスタンスである ActiveFilter::Base オブジェクトの
|
80
|
+
# インスタンス変数にモデルの型を格納
|
81
|
+
unless klass.ancestors.include?(ActiveRecord::Base)
|
82
|
+
raise ArgumentError.new("klass required inherit ActiveRecord::Base")
|
46
83
|
end
|
84
|
+
@model = klass
|
47
85
|
end
|
48
86
|
|
49
87
|
def self.fields(*names)
|
50
|
-
|
51
|
-
|
52
|
-
|
88
|
+
# Class クラスのインスタンスである ActiveFilter::Base オブジェクトの
|
89
|
+
# インスタンス変数にフィールド名を格納
|
90
|
+
@field_names = names
|
53
91
|
end
|
54
92
|
|
55
93
|
public
|
@@ -57,10 +95,6 @@ module ActiveFilter
|
|
57
95
|
self.class._model
|
58
96
|
end
|
59
97
|
|
60
|
-
def rules
|
61
|
-
self.class._rules
|
62
|
-
end
|
63
|
-
|
64
98
|
def each(&block)
|
65
99
|
scope = self.to_scope
|
66
100
|
unless block_given?
|
@@ -74,14 +108,33 @@ module ActiveFilter
|
|
74
108
|
end
|
75
109
|
|
76
110
|
def to_scope
|
77
|
-
scope =
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
111
|
+
scope = _scoped
|
112
|
+
|
113
|
+
@fields.each do |field|
|
114
|
+
# フィールド名でフィルタする
|
115
|
+
name = field.name
|
116
|
+
if @data.include?(name)
|
117
|
+
converted_value = field.convert_value(@data[name])
|
118
|
+
scope = field.filter(scope, converted_value, "extract")
|
119
|
+
elsif @data.include?(name.to_sym)
|
120
|
+
converted_value = field.convert_value(@data[name.to_sym])
|
121
|
+
scope = field.filter(scope, converted_value, "extract")
|
122
|
+
end
|
123
|
+
|
124
|
+
# lookup_type でフィルタする
|
125
|
+
lookup_types = [field.lookup_type].flatten
|
126
|
+
lookup_types.each do |lookup_type|
|
127
|
+
lookup = "#{name}__#{lookup_type}"
|
128
|
+
if @data.include?(lookup)
|
129
|
+
converted_value = field.convert_value(@data[lookup])
|
130
|
+
scope = field.filter(scope, converted_value, lookup_type)
|
131
|
+
elsif @data.include?(lookup.to_sym)
|
132
|
+
converted_value = field.convert_value(@data[lookup.to_sym])
|
133
|
+
scope = field.filter(scope, converted_value, lookup_type)
|
134
|
+
end
|
83
135
|
end
|
84
136
|
end
|
137
|
+
|
85
138
|
scope
|
86
139
|
end
|
87
140
|
end
|
data/lib/active_filter/engine.rb
CHANGED
@@ -0,0 +1,93 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require "active_support"
|
3
|
+
|
4
|
+
module ActiveFilter
|
5
|
+
class Field
|
6
|
+
attr_reader :name
|
7
|
+
|
8
|
+
def initialize(name)
|
9
|
+
@name = name.to_s
|
10
|
+
end
|
11
|
+
|
12
|
+
def convert_value(value)
|
13
|
+
value
|
14
|
+
end
|
15
|
+
|
16
|
+
def lookup_type
|
17
|
+
"extract"
|
18
|
+
end
|
19
|
+
|
20
|
+
def filter(scope, value, lookup_type)
|
21
|
+
case lookup_type
|
22
|
+
when "extract"
|
23
|
+
return scope.where("#{@name} = ?", value)
|
24
|
+
when "gt"
|
25
|
+
return scope.where("#{@name} > ?", value)
|
26
|
+
when "lt"
|
27
|
+
return scope.where("#{@name} < ?", value)
|
28
|
+
else
|
29
|
+
raise ArgumentError.new("#{lookup_type} is not supported.")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class StringField < Field;end
|
35
|
+
class TextField < Field;end
|
36
|
+
|
37
|
+
class IntegerField < Field
|
38
|
+
def lookup_type
|
39
|
+
["extract", "gt", "lt"]
|
40
|
+
end
|
41
|
+
|
42
|
+
def convert_value(value)
|
43
|
+
value.to_i
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class FloatField < IntegerField
|
48
|
+
def convert_value(value)
|
49
|
+
value.to_f
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class DecimalField < IntegerField;end
|
54
|
+
|
55
|
+
class DateTimeField < Field
|
56
|
+
def lookup_type
|
57
|
+
["extract", "gt", "lt"]
|
58
|
+
end
|
59
|
+
|
60
|
+
def convert_value(value)
|
61
|
+
value.to_datetime
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class DateField < DateTimeField
|
66
|
+
def convert_value(value)
|
67
|
+
value.to_date
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class TimeField < DateTimeField
|
72
|
+
def convert_value(value)
|
73
|
+
value.to_time
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class BooleanField < Field
|
78
|
+
def convert_value(value)
|
79
|
+
compare_value = value.is_a?(String) ? value.downcase : value
|
80
|
+
case compare_value
|
81
|
+
when "no", "false", false, "0", 0
|
82
|
+
false
|
83
|
+
when "yes", "true", true, "1", 1
|
84
|
+
true
|
85
|
+
when nil
|
86
|
+
false
|
87
|
+
else
|
88
|
+
!!compare_value
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
data/lib/active_filter.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_filter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,24 +9,40 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3'
|
14
30
|
- !ruby/object:Gem::Dependency
|
15
31
|
name: rails
|
16
32
|
requirement: !ruby/object:Gem::Requirement
|
17
33
|
none: false
|
18
34
|
requirements:
|
19
|
-
- -
|
35
|
+
- - ! '>='
|
20
36
|
- !ruby/object:Gem::Version
|
21
|
-
version: 3
|
37
|
+
version: '3'
|
22
38
|
type: :runtime
|
23
39
|
prerelease: false
|
24
40
|
version_requirements: !ruby/object:Gem::Requirement
|
25
41
|
none: false
|
26
42
|
requirements:
|
27
|
-
- -
|
43
|
+
- - ! '>='
|
28
44
|
- !ruby/object:Gem::Version
|
29
|
-
version: 3
|
45
|
+
version: '3'
|
30
46
|
- !ruby/object:Gem::Dependency
|
31
47
|
name: sqlite3
|
32
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,6 +75,22 @@ dependencies:
|
|
59
75
|
- - ! '>='
|
60
76
|
- !ruby/object:Gem::Version
|
61
77
|
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rspec-rails
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
62
94
|
description: ActiveFilter is a Rails engine for allowing users to filter scope dynamically.
|
63
95
|
email:
|
64
96
|
- griefworker@gmail.com
|
@@ -68,8 +100,8 @@ extra_rdoc_files: []
|
|
68
100
|
files:
|
69
101
|
- lib/active_filter/base.rb
|
70
102
|
- lib/active_filter/engine.rb
|
103
|
+
- lib/active_filter/field.rb
|
71
104
|
- lib/active_filter/railtie.rb
|
72
|
-
- lib/active_filter/rule.rb
|
73
105
|
- lib/active_filter/version.rb
|
74
106
|
- lib/active_filter.rb
|
75
107
|
- lib/generators/active_filter/filter_generator.rb
|
@@ -92,7 +124,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
92
124
|
version: '0'
|
93
125
|
segments:
|
94
126
|
- 0
|
95
|
-
hash: -
|
127
|
+
hash: -3354574353873881808
|
96
128
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
129
|
none: false
|
98
130
|
requirements:
|
@@ -101,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
101
133
|
version: '0'
|
102
134
|
segments:
|
103
135
|
- 0
|
104
|
-
hash: -
|
136
|
+
hash: -3354574353873881808
|
105
137
|
requirements: []
|
106
138
|
rubyforge_project:
|
107
139
|
rubygems_version: 1.8.24
|
data/lib/active_filter/rule.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
module ActiveFilter
|
4
|
-
class Rule
|
5
|
-
attr_reader :pattern
|
6
|
-
|
7
|
-
def initialize(pattern, &block)
|
8
|
-
@pattern = pattern
|
9
|
-
@block = block
|
10
|
-
end
|
11
|
-
|
12
|
-
def match?(value)
|
13
|
-
@regexp ||= Regexp.new(@pattern)
|
14
|
-
matched = (@regexp =~ value.to_s)
|
15
|
-
!matched.nil?
|
16
|
-
end
|
17
|
-
|
18
|
-
def filter(scope, value)
|
19
|
-
@block.call(scope, value)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|