search_fu 0.0.8.beta → 0.9.0
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/lib/search_fu.rb +1 -1
- data/lib/search_fu/model_additions.rb +112 -107
- data/lib/search_fu/version.rb +1 -1
- data/lib/search_fu/view_helper.rb +2 -2
- data/lib/search_fu_attribute.rb +25 -0
- data/lib/search_fu_attributes.rb +33 -0
- data/search_fu.gemspec +1 -0
- data/spec/model_additions_spec.rb +135 -0
- data/spec/schema.rb +0 -9
- data/spec/search_fu_attribute_spec.rb +51 -0
- data/spec/search_fu_attributes_spec.rb +73 -0
- data/spec/spec_helper.rb +0 -19
- metadata +61 -15
- data/spec/search_fu_spec.rb +0 -31
data/lib/search_fu.rb
CHANGED
@@ -1,127 +1,132 @@
|
|
1
|
+
require 'search_fu_attributes'
|
2
|
+
|
1
3
|
module SearchFu
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
|
11
|
+
def search_fu name, view_name=nil, query=nil
|
12
|
+
@search_fu_attrs ||= SearchFuAttributes.new
|
13
|
+
@search_fu_attrs << SearchFuAttribute.new(name, view_name, query)
|
8
14
|
end
|
9
15
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@rel << generate_where(search_fu_attr, v[:value])
|
19
|
-
end
|
20
|
-
rtnval.instance_eval(@rel.join('.'))
|
21
|
-
end
|
16
|
+
def search params={}
|
17
|
+
output = respond_to?(:search_fu_before) ? search_fu_before : where(nil)
|
18
|
+
params.each do |k, v|
|
19
|
+
query = search_fu_query(v[:name]).call(v[:value])
|
20
|
+
output = output.nil? ? query : output.merge(query)
|
21
|
+
end if params
|
22
|
+
output
|
23
|
+
end
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
a << h[:name]
|
27
|
-
end
|
28
|
-
a
|
29
|
-
end
|
25
|
+
def search_fu_view_names
|
26
|
+
@search_fu_attrs.view_names
|
27
|
+
end
|
30
28
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
29
|
+
def eval_text text, *term
|
30
|
+
op_text = replace_operator_tag_with_sql_operator(text, term.join)
|
31
|
+
op_val_text = replace_value_tag_with_eval_text(op_text, term.join)
|
32
|
+
class_eval op_val_text
|
33
|
+
end
|
36
34
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
val = attr[:convert].call(op, a[1]) if attr[:convert]
|
45
|
-
if attr[:ar_query].class == Proc
|
46
|
-
w = attr[:ar_query].call
|
47
|
-
else
|
48
|
-
w = attr[:ar_query]
|
49
|
-
end
|
50
|
-
w.gsub(/<op>/, op).gsub(/<value>/, val)
|
35
|
+
def where sql, *term
|
36
|
+
if use_fu_where? sql
|
37
|
+
op_sql = replace_operator_tag_with_sql_operator(sql, term.join)
|
38
|
+
op_val_sql = replace_value_tag_with_sql_value(op_sql, term.join)
|
39
|
+
super op_val_sql
|
40
|
+
else
|
41
|
+
super
|
51
42
|
end
|
43
|
+
end
|
52
44
|
|
53
|
-
|
54
|
-
op == "like" ? "%#{val.to_s}%" : val.to_s
|
55
|
-
end
|
45
|
+
private
|
56
46
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
a.delete_at(0) if operator
|
61
|
-
[operator, a.join(' ')]
|
62
|
-
end
|
47
|
+
def search_fu_query name
|
48
|
+
query = @search_fu_attrs.find!(name).query || generate_query(name)
|
49
|
+
end
|
63
50
|
|
64
|
-
|
65
|
-
|
66
|
-
|
51
|
+
def generate_query name
|
52
|
+
colname = @search_fu_attrs.find!(name).column_name
|
53
|
+
lambda { |val| where("#{table_name}.#{colname} <_op_> <_val_>", val) }
|
54
|
+
end
|
67
55
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
if args.size == 2
|
77
|
-
search_fu_attribute_hash(args[1], ar_query(args[0], hash))
|
78
|
-
elsif args.size == 1
|
79
|
-
search_fu_attribute_hash(args[0].to_s.humanize, ar_query(args[0], hash))
|
80
|
-
end
|
81
|
-
end
|
56
|
+
def operator_hash
|
57
|
+
{ "~" => "like", "=" => "=", "=>" => ">=", "=<" => "<=", ">=" => ">=",
|
58
|
+
"<=" => "<=", "<" => "<", ">" => ">", "<>" => "<>", "!=" => "<>" }
|
59
|
+
end
|
60
|
+
|
61
|
+
def operator_regexp
|
62
|
+
Regexp.new("^(" + operator_hash.map {|k, v| k }.sort_by {|t| 15 - t.length }.join("|") + ")?(.+)?")
|
63
|
+
end
|
82
64
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
65
|
+
def replace_value_tag_with_eval_text string, term
|
66
|
+
value = to_sql_value(grab_value_from(term), to_sql_operator(grab_operator_from(term)), true)
|
67
|
+
return string.gsub(/\<_val_\>/, value) if value
|
68
|
+
string
|
69
|
+
end
|
70
|
+
|
71
|
+
def replace_value_tag_with_sql_value string, term
|
72
|
+
value = to_sql_value(grab_value_from(term), to_sql_operator(grab_operator_from(term)))
|
73
|
+
return string.gsub(/\<_val_\>/, value) if value
|
74
|
+
string
|
75
|
+
end
|
76
|
+
|
77
|
+
def replace_operator_tag_with_sql_operator string, term
|
78
|
+
string.gsub /\<_op_\>/, to_sql_operator(grab_operator_from(term))
|
79
|
+
end
|
80
|
+
|
81
|
+
def operator_by_value_type val
|
82
|
+
parse_float(val) || parse_date(val) ? "=" : "~" if val
|
83
|
+
end
|
84
|
+
|
85
|
+
def grab_value_from term
|
86
|
+
term.scan(operator_regexp).flatten.map { |t| t.nil? ? t : t.strip }[1]
|
87
|
+
end
|
88
|
+
|
89
|
+
def to_sql_value val, operator, no_wild_card=false
|
90
|
+
if operator != 'like' and val
|
91
|
+
parse_float(val) || parse_date(val) || "'#{val}'"
|
92
|
+
else
|
93
|
+
no_wild_card ? "'#{val}'" : "'%#{val}%'"
|
108
94
|
end
|
95
|
+
end
|
109
96
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
97
|
+
def grab_operator_from term
|
98
|
+
term.scan(operator_regexp).flatten.map{ |t| t.nil? ? t : t.strip }[0] ||
|
99
|
+
operator_by_value_type(grab_value_from(term))
|
100
|
+
end
|
101
|
+
|
102
|
+
def parse_float value
|
103
|
+
(Float value).to_s
|
104
|
+
rescue ArgumentError
|
105
|
+
nil
|
106
|
+
end
|
107
|
+
|
108
|
+
def parse_date value
|
109
|
+
regex = /^(\d{1,2}(\/|\-|\.)\d{1,2}(\/|\-|\.)\d{4})$|^(\d{4}(\/|\-|\.)\d{1,2}(\/|\-|\.)\d{1,2})$|^(\d{1,2}(\/|\-|\.)[a-z]{3}(\/|\-|\.)\d{4}$)/
|
110
|
+
if value =~ regex
|
111
|
+
"'#{Date.parse(value).to_s(:db)}'"
|
112
|
+
else
|
113
|
+
nil
|
118
114
|
end
|
115
|
+
end
|
119
116
|
|
117
|
+
def to_sql_operator(val)
|
118
|
+
return '' if val.nil?
|
119
|
+
operator_hash[val]
|
120
120
|
end
|
121
|
+
|
122
|
+
def use_fu_where? opts
|
123
|
+
if opts.kind_of? String
|
124
|
+
opts.scan(/\<_op_\>|\<_val_\>/).count > 0 ? true : false
|
125
|
+
else
|
126
|
+
false
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
121
130
|
end
|
122
|
-
end
|
123
131
|
|
124
|
-
if defined?(ActiveRecord::Base)
|
125
|
-
ActiveRecord::Base.send :include, SearchFu::ModelAdditions
|
126
132
|
end
|
127
|
-
|
data/lib/search_fu/version.rb
CHANGED
@@ -27,7 +27,7 @@ module SearchFu
|
|
27
27
|
(session["#{model_klass.name.underscore}_search_fu"] || params[:search_fu] || {}).each do |k,v|
|
28
28
|
rand_id = (DateTime.now.to_i * rand * 100).to_i
|
29
29
|
html << content_tag(:tr, id: "search_fu_row_new_#{rand_id}", class: "search_fu_rows") do
|
30
|
-
content_tag(:td, select_tag("search_fu[_new_#{rand_id}][name]", options_for_select(model_klass.
|
30
|
+
content_tag(:td, select_tag("search_fu[_new_#{rand_id}][name]", options_for_select(model_klass.search_fu_view_names, v[:name]))) +
|
31
31
|
content_tag(:td, text_field_tag("search_fu[_new_#{rand_id}][value]", v[:value])) +
|
32
32
|
content_tag(:td, link_to("X", "#", class: "search_fu_remove #{remove_button_class}"))
|
33
33
|
end
|
@@ -53,7 +53,7 @@ module SearchFu
|
|
53
53
|
content_tag(:table, style: "display:none") do
|
54
54
|
content_tag(:tbody, id: "hidden_search_fields") do
|
55
55
|
content_tag(:tr, id: "search_fu_row_NEW_", class: "search_fu_rows") do
|
56
|
-
content_tag(:td, select_tag("search_fu[_NEW_][name]", options_for_select(model_klass.
|
56
|
+
content_tag(:td, select_tag("search_fu[_NEW_][name]", options_for_select(model_klass.search_fu_view_names))) +
|
57
57
|
content_tag(:td, text_field_tag("search_fu[_NEW_][value]")) +
|
58
58
|
content_tag(:td, link_to("X", "#", class: "search_fu_remove #{remove_button_class}"))
|
59
59
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
class SearchFuAttribute
|
4
|
+
attr_accessor :column_name, :view_name, :query
|
5
|
+
|
6
|
+
def initialize name, view_name=nil, query=nil
|
7
|
+
@column_name = name
|
8
|
+
@view_name = humanzie_symbol name
|
9
|
+
@query = query if query
|
10
|
+
@query = view_name if view_name.respond_to? :call
|
11
|
+
if view_name and !view_name.respond_to? :call
|
12
|
+
@view_name = humanzie_symbol view_name
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def humanzie_symbol name
|
18
|
+
if name.kind_of? Symbol
|
19
|
+
ActiveSupport::Inflector.humanize name.to_s
|
20
|
+
else
|
21
|
+
name
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'search_fu_attribute'
|
2
|
+
|
3
|
+
class SearchFuAttributes < Array
|
4
|
+
class DuplicateViewName < RuntimeError; end
|
5
|
+
class NotSearchFuAttribute < RuntimeError; end
|
6
|
+
class ViewNameNotFound < RuntimeError; end
|
7
|
+
|
8
|
+
def << value
|
9
|
+
raise NotSearchFuAttribute if !value.kind_of? SearchFuAttribute
|
10
|
+
if find value.view_name
|
11
|
+
raise DuplicateViewName
|
12
|
+
else
|
13
|
+
super
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def view_names
|
18
|
+
self.map { |t| t.view_name }
|
19
|
+
end
|
20
|
+
|
21
|
+
def find view_name
|
22
|
+
self.detect { |t| t.view_name == view_name }
|
23
|
+
end
|
24
|
+
|
25
|
+
def find! view_name
|
26
|
+
a = find view_name
|
27
|
+
raise ViewNameNotFound unless a
|
28
|
+
a
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
|
data/search_fu.gemspec
CHANGED
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'search_fu'
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe "SearchFu module" do
|
6
|
+
class Payment < ActiveRecord::Base
|
7
|
+
include SearchFu
|
8
|
+
belongs_to :account
|
9
|
+
scope :search_fu_before, where("10=10")
|
10
|
+
search_fu :note, "Description"
|
11
|
+
search_fu "Debit Account Name", lambda { |val| where("accounts.name1 <_op_> <_val_>", val).joins(:account) }
|
12
|
+
search_fu "Credit Account Name", lambda { |val| eval_text(%(where("note <_op_> <_val_>")), val) }
|
13
|
+
end
|
14
|
+
|
15
|
+
class Account < ActiveRecord::Base
|
16
|
+
include SearchFu
|
17
|
+
has_many :payments
|
18
|
+
search_fu :name1, lambda { |val| where("name1 <_op_> <_val_>", val) }
|
19
|
+
search_fu :name2, lambda { |val| where("name2 <_op_> <_val_>", val) }
|
20
|
+
search_fu :status, "Current Status"
|
21
|
+
search_fu :description
|
22
|
+
end
|
23
|
+
|
24
|
+
it "#search should retrun where(nil) if params == nil or params not provided" do
|
25
|
+
Account.search.to_sql.should == Account.where(nil).to_sql
|
26
|
+
Account.search(nil).to_sql.should == Account.where(nil).to_sql
|
27
|
+
end
|
28
|
+
|
29
|
+
it "search_fu_before should be where(nil) if not provided" do
|
30
|
+
Account.search.to_sql.should == Account.where(nil).to_sql
|
31
|
+
end
|
32
|
+
|
33
|
+
it "eval_text should change op val and eval result" do
|
34
|
+
Payment.search( a: { name: "Credit Account Name", value: "haha" } ).to_sql.should ==
|
35
|
+
Payment.where("10=10").where("note like 'haha'").to_sql
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should combine search_fu_before scope, if exists" do
|
39
|
+
Payment.search( a: { name: "Debit Account Name", value: "haha" } ).to_sql.should ==
|
40
|
+
Payment.where("10=10").where("accounts.name1 like '%haha%'").joins(:account).to_sql
|
41
|
+
end
|
42
|
+
|
43
|
+
context "#search" do
|
44
|
+
context "will generate default query" do
|
45
|
+
it "if not provided, type C" do
|
46
|
+
Payment.search( a: { name: "Debit Account Name", value: "haha" } ).to_sql.should ==
|
47
|
+
Payment.where("10=10").where("accounts.name1 like '%haha%'").joins(:account).to_sql
|
48
|
+
end
|
49
|
+
|
50
|
+
it "if not provided, type A" do
|
51
|
+
Account.search( a: { name: "Current Status", value: "haha" } ).to_sql.should ==
|
52
|
+
Account.where("accounts.status like '%haha%'").to_sql
|
53
|
+
end
|
54
|
+
|
55
|
+
it "if not provided, type B" do
|
56
|
+
Account.search( a: { name: "Description", value: "haha" } ).to_sql.should ==
|
57
|
+
Account.where("accounts.description like '%haha%'").to_sql
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should return ActiveRecord::Relation" do
|
62
|
+
Account.search( a: { name: "Name1", value: "stuff" }).class.should == ActiveRecord::Relation
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should call search_fu lambda" do
|
66
|
+
Account.search( a: { name: "Name1", value: "stuff" }).to_sql.should ==
|
67
|
+
Account.where("name1 like '%stuff%'").to_sql
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should combine lambda if more than 1 search_fu params" do
|
71
|
+
Account.search(a: { name: "Name1", value: "stuff"}, b: { name: "Name2", value: "stuff1"}).to_sql.should ==
|
72
|
+
Account.where("name1 like '%stuff%'").where("name2 like '%stuff1%'").to_sql
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "#where should provide default operator" do
|
77
|
+
it "= for numeric value and convert value to float" do
|
78
|
+
Account.where("name1 <_op_> <_val_>", "32").to_sql.should ==
|
79
|
+
Account.where("name1 = 32.0").to_sql
|
80
|
+
end
|
81
|
+
|
82
|
+
it "= for date value and convert value to db date format" do
|
83
|
+
Account.where("name1 <_op_> <_val_>", "31-dec-2011").to_sql.should ==
|
84
|
+
Account.where("name1 = '2011-12-31'").to_sql
|
85
|
+
end
|
86
|
+
|
87
|
+
it "like for string value and convert value to %value%" do
|
88
|
+
Account.where("name1 <_op_> <_val_>", "jimmy").to_sql.should ==
|
89
|
+
Account.where("name1 like '%jimmy%'").to_sql
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "#where replace <_val_>" do
|
94
|
+
it "should quote string" do
|
95
|
+
Account.where("name1 <_op_> <_val_>", "= somevalue").to_sql.should ==
|
96
|
+
Account.where("name1 = 'somevalue'").to_sql
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should convert and quote date" do
|
100
|
+
Account.where("name1 <_op_> <_val_>", "= 31-dec-2011").to_sql.should ==
|
101
|
+
Account.where("name1 = '2011-12-31'").to_sql
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should convert to float and not quote numeric" do
|
105
|
+
Account.where("name1 <_op_> <_val_>", "= 2011").to_sql.should ==
|
106
|
+
Account.where("name1 = 2011.0").to_sql
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "#where should replace <_op_>" do
|
111
|
+
{ "~" => "like", "=" => "=", "=>" => ">=", "=<" => "<=", ">=" => ">=", "<=" => "<=",
|
112
|
+
"<" => "<", ">" => ">", "<>" => "<>", "!=" => "<>" }.each do |fc_op, sql_op|
|
113
|
+
it "#{fc_op} to #{sql_op}" do
|
114
|
+
Account.where("name1 <_op_> 'somevalue'", "#{fc_op}").to_sql.should ==
|
115
|
+
Account.where("name1 #{sql_op} 'somevalue'").to_sql
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
it "#where should not replace <_op_> if not provided" do
|
121
|
+
Account.where("name1 <_op_> 'somevalue'", '').to_sql.should ==
|
122
|
+
Account.where("name1 <_op_> 'somevalue'").to_sql
|
123
|
+
end
|
124
|
+
|
125
|
+
it "#where should not replace operator if no <_op_>" do
|
126
|
+
Account.where("name1 = 'somevalue'", '<>').to_sql.should ==
|
127
|
+
Account.where("name1 = 'somevalue'").to_sql
|
128
|
+
end
|
129
|
+
|
130
|
+
it "#search_fu_view_names should has a view_names" do
|
131
|
+
Account.search_fu_view_names.should == ["Name1", "Name2", "Current Status", "Description"]
|
132
|
+
Payment.search_fu_view_names.should == ["Description", "Debit Account Name", "Credit Account Name"]
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
data/spec/schema.rb
CHANGED
@@ -3,26 +3,17 @@ ActiveRecord::Schema.define do
|
|
3
3
|
create_table "accounts", :force => true do |t|
|
4
4
|
t.string "name1", :null => false
|
5
5
|
t.string "name2"
|
6
|
-
t.integer "institution_id", :null => false
|
7
|
-
t.string "account_type_id", :null => false
|
8
6
|
t.text "description"
|
9
7
|
t.string "status", :default => "Active"
|
10
8
|
t.integer "lock_version"
|
11
9
|
end
|
12
10
|
|
13
11
|
create_table "payments", :force => true do |t|
|
14
|
-
t.integer "institution_id"
|
15
12
|
t.date "date"
|
16
13
|
t.string "collector"
|
17
14
|
t.integer "to_account_id"
|
18
15
|
t.integer "from_account_id"
|
19
|
-
t.string "cheque_no"
|
20
|
-
t.date "cheque_date"
|
21
|
-
t.string "currency"
|
22
16
|
t.integer "c_amount", :default => 0
|
23
|
-
t.integer "charges_account_id"
|
24
|
-
t.string "charges_particulars"
|
25
|
-
t.integer "c_charges_amount", :default => 0
|
26
17
|
t.text "note"
|
27
18
|
t.string "status"
|
28
19
|
t.integer "lock_version", :default => 0
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'search_fu_attribute'
|
2
|
+
|
3
|
+
describe SearchFuAttribute do
|
4
|
+
|
5
|
+
it "should have attr_accessor :view_name" do
|
6
|
+
SearchFuAttribute.new(:haha).respond_to?(:view_name).should be_true
|
7
|
+
SearchFuAttribute.new(:haha).respond_to?(:view_name=).should be_true
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should have attr_accessor :query" do
|
11
|
+
SearchFuAttribute.new(:haha).respond_to?(:query).should be_true
|
12
|
+
SearchFuAttribute.new(:haha).respond_to?(:query=).should be_true
|
13
|
+
end
|
14
|
+
|
15
|
+
context "initialize" do
|
16
|
+
|
17
|
+
it "" do
|
18
|
+
SearchFuAttribute.new(:haha_baba).view_name.should == "Haha baba"
|
19
|
+
end
|
20
|
+
|
21
|
+
context "name != nil, view_name != nil, query == nil" do
|
22
|
+
it "should store humanize view_name or plain view_name" do
|
23
|
+
SearchFuAttribute.new(:haha, "HAHA BABA").view_name.should == "HAHA BABA"
|
24
|
+
SearchFuAttribute.new(:haha, :mama_papa).view_name.should == "Mama papa"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "name != nil, view_name == query, query == nil" do
|
29
|
+
it "should store humanize name as view_name and store view_name as query" do
|
30
|
+
a = SearchFuAttribute.new("HAHA BABA", lambda { 123 })
|
31
|
+
a.view_name.should == "HAHA BABA"
|
32
|
+
a.query.call.should == 123
|
33
|
+
b = SearchFuAttribute.new(:mama_papa, lambda { 321})
|
34
|
+
b.view_name.should == "Mama papa"
|
35
|
+
b.query.call.should == 321
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "name != nil, view_name != nil, query != nil" do
|
40
|
+
it "should store view_name and store query" do
|
41
|
+
a = SearchFuAttribute.new(:haha, "HAHA BABA", lambda { 123 })
|
42
|
+
a.view_name.should == "HAHA BABA"
|
43
|
+
a.query.call.should == 123
|
44
|
+
b = SearchFuAttribute.new(:haha, :mama_papa, lambda { 321})
|
45
|
+
b.view_name.should == "Mama papa"
|
46
|
+
b.query.call.should == 321
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'search_fu_attributes'
|
2
|
+
require 'search_fu_attribute'
|
3
|
+
|
4
|
+
describe SearchFuAttributes do
|
5
|
+
|
6
|
+
it "should raise error if insert class is not SearchFuAttribute" do
|
7
|
+
a = SearchFuAttributes.new
|
8
|
+
expect do
|
9
|
+
a << "fdsfsa"
|
10
|
+
end.to raise_error SearchFuAttributes::NotSearchFuAttribute
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should not raise error if insert class is SearchFuAttribute" do
|
14
|
+
a = SearchFuAttributes.new
|
15
|
+
expect do
|
16
|
+
a << SearchFuAttribute.new(:fdsfas)
|
17
|
+
end.not_to raise_error SearchFuAttributes::NotSearchFuAttribute
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should raise error if duplicate view_name was added" do
|
21
|
+
a = SearchFuAttributes.new
|
22
|
+
a << SearchFuAttribute.new(:aaaa)
|
23
|
+
expect do
|
24
|
+
a << SearchFuAttribute.new(:aaaa)
|
25
|
+
end.to raise_error SearchFuAttributes::DuplicateViewName
|
26
|
+
a.count.should == 1
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should not raise error if not duplicate view_name was added" do
|
30
|
+
a = SearchFuAttributes.new
|
31
|
+
a << SearchFuAttribute.new(:aaaa)
|
32
|
+
a << SearchFuAttribute.new(:bbbb)
|
33
|
+
a.count.should == 2
|
34
|
+
end
|
35
|
+
|
36
|
+
it "find should return nil" do
|
37
|
+
a = SearchFuAttributes.new
|
38
|
+
a << SearchFuAttribute.new(:aaaa)
|
39
|
+
a << SearchFuAttribute.new(:bbbb)
|
40
|
+
a.find("AAAA").should be_nil
|
41
|
+
end
|
42
|
+
|
43
|
+
it "find should return Aaaa" do
|
44
|
+
a = SearchFuAttributes.new
|
45
|
+
a << SearchFuAttribute.new(:aaaa)
|
46
|
+
a << SearchFuAttribute.new(:bbbb)
|
47
|
+
a.find("Aaaa").should == a[0]
|
48
|
+
end
|
49
|
+
|
50
|
+
it "find! should raise error" do
|
51
|
+
a = SearchFuAttributes.new
|
52
|
+
a << SearchFuAttribute.new(:aaaa)
|
53
|
+
a << SearchFuAttribute.new(:bbbb)
|
54
|
+
expect { a.find!("AAAA") }.to raise_error SearchFuAttributes::ViewNameNotFound
|
55
|
+
end
|
56
|
+
|
57
|
+
it "find! should return Aaaa" do
|
58
|
+
a = SearchFuAttributes.new
|
59
|
+
a << SearchFuAttribute.new(:aaaa)
|
60
|
+
a << SearchFuAttribute.new(:bbbb)
|
61
|
+
a.find!("Aaaa").should == a[0]
|
62
|
+
end
|
63
|
+
|
64
|
+
it "view_names should return Aaaa" do
|
65
|
+
a = SearchFuAttributes.new
|
66
|
+
a << SearchFuAttribute.new(:aaaa)
|
67
|
+
a << SearchFuAttribute.new(:bbbb)
|
68
|
+
a.view_names.should == ["Aaaa", "Bbbb"]
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
require 'rubygems'
|
2
1
|
require 'active_record'
|
3
|
-
require 'search_fu'
|
4
2
|
|
5
3
|
ActiveRecord::Base.establish_connection(
|
6
4
|
:adapter => 'sqlite3',
|
@@ -14,21 +12,4 @@ end
|
|
14
12
|
|
15
13
|
RSpec.configure do |config|
|
16
14
|
config.mock_with :rspec
|
17
|
-
config.before(:each) do
|
18
|
-
Payment.delete_all
|
19
|
-
Account.delete_all
|
20
|
-
end
|
21
15
|
end
|
22
|
-
|
23
|
-
class Payment < ActiveRecord::Base
|
24
|
-
belongs_to :to_account, :class_name => "Account", :foreign_key => :to_account_id
|
25
|
-
belongs_to :from_account, :class_name => "Account", :foreign_key => :from_account_id
|
26
|
-
belongs_to :charges_account, :class_name => "Account", :foreign_key => :charges_account_id
|
27
|
-
end
|
28
|
-
|
29
|
-
class Account < ActiveRecord::Base
|
30
|
-
has_many :to_payments, :class_name => 'Payment', :foreign_key => 'to_account_id'
|
31
|
-
has_many :from_payments, :class_name => 'Payment', :foreign_key => 'from_account_id'
|
32
|
-
has_many :charges_payments, :class_name => 'Payment', :foreign_key => 'charges_account_id'
|
33
|
-
end
|
34
|
-
|
metadata
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: search_fu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
5
|
-
prerelease:
|
4
|
+
version: 0.9.0
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Tan Kwang How
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-04-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sqlite3
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: rspec
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,10 +37,31 @@ dependencies:
|
|
32
37
|
version: '0'
|
33
38
|
type: :development
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
36
62
|
- !ruby/object:Gem::Dependency
|
37
63
|
name: activerecord
|
38
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
39
65
|
none: false
|
40
66
|
requirements:
|
41
67
|
- - ! '>='
|
@@ -43,10 +69,15 @@ dependencies:
|
|
43
69
|
version: '0'
|
44
70
|
type: :runtime
|
45
71
|
prerelease: false
|
46
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
47
78
|
- !ruby/object:Gem::Dependency
|
48
79
|
name: actionpack
|
49
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
50
81
|
none: false
|
51
82
|
requirements:
|
52
83
|
- - ! '>='
|
@@ -54,7 +85,12 @@ dependencies:
|
|
54
85
|
version: '0'
|
55
86
|
type: :runtime
|
56
87
|
prerelease: false
|
57
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
58
94
|
description: A ActiveRecord method to allow user specify and combine query in views
|
59
95
|
email:
|
60
96
|
- tankwanghow@gmail.com
|
@@ -72,9 +108,13 @@ files:
|
|
72
108
|
- lib/search_fu/model_additions.rb
|
73
109
|
- lib/search_fu/version.rb
|
74
110
|
- lib/search_fu/view_helper.rb
|
111
|
+
- lib/search_fu_attribute.rb
|
112
|
+
- lib/search_fu_attributes.rb
|
75
113
|
- search_fu.gemspec
|
114
|
+
- spec/model_additions_spec.rb
|
76
115
|
- spec/schema.rb
|
77
|
-
- spec/
|
116
|
+
- spec/search_fu_attribute_spec.rb
|
117
|
+
- spec/search_fu_attributes_spec.rb
|
78
118
|
- spec/spec_helper.rb
|
79
119
|
homepage: http://github.com/tankwanghow
|
80
120
|
licenses: []
|
@@ -88,15 +128,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
88
128
|
- - ! '>='
|
89
129
|
- !ruby/object:Gem::Version
|
90
130
|
version: '0'
|
131
|
+
segments:
|
132
|
+
- 0
|
133
|
+
hash: -403552339
|
91
134
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
135
|
none: false
|
93
136
|
requirements:
|
94
|
-
- - ! '
|
137
|
+
- - ! '>='
|
95
138
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
139
|
+
version: '0'
|
140
|
+
segments:
|
141
|
+
- 0
|
142
|
+
hash: -403552339
|
97
143
|
requirements: []
|
98
144
|
rubyforge_project: search_fu
|
99
|
-
rubygems_version: 1.8.
|
145
|
+
rubygems_version: 1.8.21
|
100
146
|
signing_key:
|
101
147
|
specification_version: 3
|
102
148
|
summary: Combine query in views
|
data/spec/search_fu_spec.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe SearchFu::ModelAdditions do
|
4
|
-
describe '.search_fu_attribute_hash' do
|
5
|
-
it "should raise error if hash[:ar_query] not found" do
|
6
|
-
lambda { SearchFu.search_fu_attribute_hash('name', {}) }.should raise_error("No Query found in hash!")
|
7
|
-
end
|
8
|
-
|
9
|
-
it "should not rails error if hash[:ar_query] exists" do
|
10
|
-
lambda { SearchFu.search_fu_attribute_hash('name', ar_query: 3) }.should_not raise_error("No Query found in hash!")
|
11
|
-
end
|
12
|
-
|
13
|
-
describe 'return hash' do
|
14
|
-
it "should be hashed correctly" do
|
15
|
-
SearchFu.search_fu_attribute_hash("stuff", ar_query: 'haha').should ==
|
16
|
-
{ name: 'stuff', ar_query: 'haha', operator: nil, convert: nil }
|
17
|
-
|
18
|
-
SearchFu.search_fu_attribute_hash("stuff", ar_query: 'haha', operator: 'kaka').should ==
|
19
|
-
{ name: 'stuff', ar_query: 'haha', operator: 'kaka', convert: nil }
|
20
|
-
|
21
|
-
SearchFu.search_fu_attribute_hash("stuff", ar_query: 'haha', convert: 'caca').should ==
|
22
|
-
{ name: 'stuff', ar_query: 'haha', operator: nil, convert: 'caca' }
|
23
|
-
|
24
|
-
SearchFu.search_fu_attribute_hash("stuff", ar_query: 'haha', convert: 'caca', operator: 'kaka' ).should ==
|
25
|
-
{ name: 'stuff', ar_query: 'haha', operator: 'kaka', convert: 'caca' }
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
31
|
-
|