active_filter 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,62 +1,88 @@
1
1
  # coding: utf-8
2
- require "active_filter/field"
2
+ require "active_filter/filter"
3
3
 
4
4
  module ActiveFilter
5
5
  class Base
6
- attr_reader :fields
6
+ include ::Enumerable
7
+
8
+ attr_reader :filters
7
9
 
8
10
  def initialize(data, scope=nil)
9
11
  @data = data
10
12
  @scope = scope
11
13
 
12
- @fields = []
13
- self.class._model.columns.each do |column|
14
- if self.class._field_names.include?(column.name) ||
15
- self.class._field_names.include?(column.name.to_sym)
16
- @fields << _create_field_from_column(column)
17
- end
14
+ columns = self.class._model.columns
15
+
16
+ # fields で指定した列だけをフィルタ可能にする
17
+ fields = self.class._fields
18
+ unless fields.empty?
19
+ columns = columns.select { |column|
20
+ fields.include?(column.name) ||
21
+ fields.include?(column.name.to_sym)
22
+ }
23
+ end
24
+
25
+ # exclude で指定した列を除外する
26
+ excludes = self.class._exclude
27
+ unless excludes.empty?
28
+ columns = columns.reject { |column|
29
+ fields.include?(column.name) ||
30
+ fields.include?(column.name.to_sym)
31
+ }
18
32
  end
33
+
34
+ @filters = columns.map { |column|
35
+ _create_filter_from_column(column)
36
+ }
19
37
  end
20
38
 
21
- private
22
- def self._field_names
23
- @field_names ||= []
39
+ def self._fields #:nodoc:
40
+ @fields ||= []
24
41
  end
25
42
 
26
- def self._model
43
+ def self._model #:nodoc:
27
44
  @model
28
45
  end
29
46
 
30
- def _create_field_from_column(column)
47
+ def self._exclude #:nodoc:
48
+ @excludes ||= []
49
+ end
50
+
51
+ def self._orders #:nodoc:
52
+ @orders ||= []
53
+ end
54
+
55
+ def _create_filter_from_column(column)
31
56
  case column.type
32
57
  when :primary_key
33
- return Field.new(column.name)
58
+ return Filter.new(column.name)
34
59
  when :string
35
- return StringField.new(column.name)
60
+ return StringFilter.new(column.name)
36
61
  when :text
37
- return TextField.new(column.name)
62
+ return TextFilter.new(column.name)
38
63
  when :integer
39
- return IntegerField.new(column.name)
64
+ return IntegerFilter.new(column.name)
40
65
  when :float
41
- return FloatField.new(column.name)
66
+ return FloatFilter.new(column.name)
42
67
  when :decimal
43
- return DecimalField.new(column.name)
68
+ return DecimalFilter.new(column.name)
44
69
  when :datetime
45
- return DateTimeField.new(column.name)
70
+ return DateTimeFilter.new(column.name)
46
71
  when :timestamp
47
- return Field.new(column.name)
72
+ return Filter.new(column.name)
48
73
  when :time
49
- return TimeField.new(column.name)
74
+ return TimeFilter.new(column.name)
50
75
  when :date
51
- return DateField.new(column.name)
76
+ return DateFilter.new(column.name)
52
77
  when :binary
53
- return Field.new(column.name)
78
+ return Filter.new(column.name)
54
79
  when :boolean
55
- return BooleanField.new(column.name)
80
+ return BooleanFilter.new(column.name)
56
81
  else
57
82
  raise ArgumentError.new("#{column.type} is not supported.")
58
83
  end
59
84
  end
85
+ private :_create_filter_from_column
60
86
 
61
87
  # コンストラクタで受け取ったスコープまたは
62
88
  # model.scoped を返す
@@ -67,8 +93,8 @@ module ActiveFilter
67
93
  @scope
68
94
  end
69
95
  end
96
+ private :_scoped
70
97
 
71
- protected
72
98
  # フィルタを作成する対象のモデルを指定します。
73
99
  def self.model(klass)
74
100
  # Class クラスのインスタンスである ActiveFilter::Base オブジェクトの
@@ -82,10 +108,17 @@ module ActiveFilter
82
108
  def self.fields(*names)
83
109
  # Class クラスのインスタンスである ActiveFilter::Base オブジェクトの
84
110
  # インスタンス変数にフィールド名を格納
85
- @field_names = names
111
+ @fields = names
112
+ end
113
+
114
+ def self.exclude(*names)
115
+ @excludes = names
116
+ end
117
+
118
+ def self.order(*names)
119
+ @orders = names
86
120
  end
87
121
 
88
- public
89
122
  def model
90
123
  self.class._model
91
124
  end
@@ -102,34 +135,33 @@ module ActiveFilter
102
135
  self
103
136
  end
104
137
 
138
+ def _lookups_from_filter(filter)
139
+ lookups = { filter.name => "exact" }
140
+
141
+ lookup_types = [filter.lookup_type].flatten
142
+ lookup_types.each do |lookup_type|
143
+ lookup = "#{filter.name}__#{lookup_type}"
144
+ lookups[lookup] = lookup_type
145
+ end
146
+
147
+ lookups
148
+ end
149
+ private :_lookups_from_filter
150
+
105
151
  def to_scope
106
152
  scope = _scoped
107
153
  matched = false
108
154
 
109
- @fields.each do |field|
110
- # フィールド名でフィルタする
111
- name = field.name
112
- if @data.include?(name)
113
- converted_value = field.convert_value(@data[name])
114
- scope = field.filter(scope, converted_value, "exact")
115
- matched = true
116
- elsif @data.include?(name.to_sym)
117
- converted_value = field.convert_value(@data[name.to_sym])
118
- scope = field.filter(scope, converted_value, "exact")
119
- matched = true
120
- end
121
-
122
- # lookup_type でフィルタする
123
- lookup_types = [field.lookup_type].flatten
124
- lookup_types.each do |lookup_type|
125
- lookup = "#{name}__#{lookup_type}"
155
+ @filters.each do |filter|
156
+ lookups = _lookups_from_filter(filter)
157
+ lookups.each do |lookup, lookup_type|
126
158
  if @data.include?(lookup)
127
- converted_value = field.convert_value(@data[lookup])
128
- scope = field.filter(scope, converted_value, lookup_type)
159
+ converted_value = filter.convert_value(@data[lookup])
160
+ scope = filter.filter(scope, converted_value, lookup_type)
129
161
  matched = true
130
162
  elsif @data.include?(lookup.to_sym)
131
- converted_value = field.convert_value(@data[lookup.to_sym])
132
- scope = field.filter(scope, converted_value, lookup_type)
163
+ converted_value = filter.convert_value(@data[lookup.to_sym])
164
+ scope = filter.filter(scope, converted_value, lookup_type)
133
165
  matched = true
134
166
  end
135
167
  end
@@ -141,6 +173,10 @@ module ActiveFilter
141
173
  scope = scope.where("1 = 2")
142
174
  end
143
175
 
176
+ self.class._orders.each do |order|
177
+ scope = scope.order(order.to_s)
178
+ end
179
+
144
180
  scope
145
181
  end
146
182
  end
@@ -2,7 +2,7 @@
2
2
  require "active_support"
3
3
 
4
4
  module ActiveFilter
5
- class Field
5
+ class Filter
6
6
  attr_reader :name
7
7
 
8
8
  def initialize(name)
@@ -37,15 +37,15 @@ module ActiveFilter
37
37
  end
38
38
  end
39
39
 
40
- class StringField < Field
40
+ class StringFilter < Filter
41
41
  def lookup_type
42
42
  ["exact", "contains"]
43
43
  end
44
44
  end
45
45
 
46
- class TextField < StringField;end
46
+ class TextFilter < StringFilter;end
47
47
 
48
- class IntegerField < Field
48
+ class IntegerFilter < Filter
49
49
  def lookup_type
50
50
  ["exact", "gt", "lt", "gte", "lte"]
51
51
  end
@@ -55,15 +55,15 @@ module ActiveFilter
55
55
  end
56
56
  end
57
57
 
58
- class FloatField < IntegerField
58
+ class FloatFilter < IntegerFilter
59
59
  def convert_value(value)
60
60
  value.to_f
61
61
  end
62
62
  end
63
63
 
64
- class DecimalField < IntegerField;end
64
+ class DecimalFilter < IntegerFilter;end
65
65
 
66
- class DateTimeField < Field
66
+ class DateTimeFilter < Filter
67
67
  def lookup_type
68
68
  ["exact", "gt", "lt", "gte", "lte"]
69
69
  end
@@ -73,19 +73,19 @@ module ActiveFilter
73
73
  end
74
74
  end
75
75
 
76
- class DateField < DateTimeField
76
+ class DateFilter < DateTimeFilter
77
77
  def convert_value(value)
78
78
  value.to_date
79
79
  end
80
80
  end
81
81
 
82
- class TimeField < DateTimeField
82
+ class TimeFilter < DateTimeFilter
83
83
  def convert_value(value)
84
84
  value.to_time
85
85
  end
86
86
  end
87
87
 
88
- class BooleanField < Field
88
+ class BooleanFilter < Filter
89
89
  def convert_value(value)
90
90
  compare_value = value.is_a?(String) ? value.downcase : value
91
91
  case compare_value
@@ -1,3 +1,3 @@
1
1
  module ActiveFilter
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
data/lib/active_filter.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # coding: utf-8
2
2
  require "active_filter/version"
3
- require "active_filter/field"
3
+ require "active_filter/filter"
4
4
  require "active_filter/base"
5
5
 
6
6
  module ActiveFilter
@@ -1,7 +1,8 @@
1
1
  class <%= class_name %>Filter < ActiveFilter::Base
2
2
  model <%= class_name %>
3
3
  <% if 0 < attributes.size %>
4
- fields <%= attributes.map{|attr| ":" + attr.name}.join(", ") %>
4
+ fields <%= attributes.map{ |attr| ":" + attr.name }.join(", ") %>
5
+ #order <%= attributes.map{ |attr| "'#{attr.name} ASC'" }.join(", ") %>
5
6
  <% end %>
6
7
  end
7
8
 
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
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-16 00:00:00.000000000 Z
12
+ date: 2013-02-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -100,7 +100,7 @@ extra_rdoc_files: []
100
100
  files:
101
101
  - lib/active_filter/base.rb
102
102
  - lib/active_filter/engine.rb
103
- - lib/active_filter/field.rb
103
+ - lib/active_filter/filter.rb
104
104
  - lib/active_filter/railtie.rb
105
105
  - lib/active_filter/version.rb
106
106
  - lib/active_filter.rb
@@ -124,7 +124,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
124
124
  version: '0'
125
125
  segments:
126
126
  - 0
127
- hash: -52441896280290827
127
+ hash: 3669060738230829906
128
128
  required_rubygems_version: !ruby/object:Gem::Requirement
129
129
  none: false
130
130
  requirements:
@@ -133,10 +133,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
133
  version: '0'
134
134
  segments:
135
135
  - 0
136
- hash: -52441896280290827
136
+ hash: 3669060738230829906
137
137
  requirements: []
138
138
  rubyforge_project:
139
- rubygems_version: 1.8.24
139
+ rubygems_version: 1.8.23
140
140
  signing_key:
141
141
  specification_version: 3
142
142
  summary: A rails engine for filtering scope based on user selections.