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 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
-