active_filter 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2012 YOURNAME
1
+ Copyright 2012 tnakamura
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -1,55 +1,93 @@
1
1
  # coding: utf-8
2
- require "active_filter/rule"
2
+ require "active_filter/field"
3
3
 
4
4
  module ActiveFilter
5
5
  class Base
6
- def initialize(params={})
7
- @params = params
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._rules
12
- # Class クラスのインスタンスである ActiveFilter::Base オブジェクトの
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
- protected
24
- def self.model(klass)
25
- @model = klass
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
- def self.rule(pattern, lmbda=nil, &block)
29
- if lmbda.nil?
30
- if block_given?
31
- callback = block
32
- else
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
- callback = lmbda
72
+ @scope
38
73
  end
39
-
40
- _rules << ActiveFilter::Rule.new(pattern, &callback)
41
74
  end
42
75
 
43
- def self.field(name)
44
- self.rule "^#{name}$" do |scope, value|
45
- scope.where(name => value)
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
- names.each do |name|
51
- self.field(name)
52
- end
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 = self.model.scoped
78
- @params.each do |key, value|
79
- # 最初にマッチしたルールを適用する
80
- rule = self.rules.find { |r| r.match?(key) }
81
- if rule
82
- scope = rule.filter(scope, value)
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
@@ -1,5 +1,8 @@
1
1
  #coding: utf-8
2
2
  module ActiveFilter #:nodoc:
3
3
  class Engine < ::Rails::Engine #:nodoc:
4
+ config.generators do |g|
5
+ g.test_framework :rspec, :view_specs => false
6
+ end
4
7
  end
5
8
  end
@@ -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
+
@@ -1,3 +1,3 @@
1
1
  module ActiveFilter
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
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/rule"
3
+ require "active_filter/field"
4
4
  require "active_filter/base"
5
5
 
6
6
  module ActiveFilter
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.2
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: 2012-11-30 00:00:00.000000000 Z
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.2.9
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.2.9
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: -3925253136135546622
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: -3925253136135546622
136
+ hash: -3354574353873881808
105
137
  requirements: []
106
138
  rubyforge_project:
107
139
  rubygems_version: 1.8.24
@@ -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
-