search_fu 0.0.1
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/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Rakefile +2 -0
- data/filter_fu.gemspec +25 -0
- data/javascript/add_remove_row.js +20 -0
- data/lib/filter_fu/controller_additions.rb +12 -0
- data/lib/filter_fu/model_additions.rb +39 -0
- data/lib/filter_fu/version.rb +3 -0
- data/lib/filter_fu/view_helper.rb +63 -0
- data/lib/filter_fu.rb +4 -0
- data/lib/search_fu/controller_additions.rb +12 -0
- data/lib/search_fu/model_additions.rb +72 -0
- data/lib/search_fu/version.rb +3 -0
- data/lib/search_fu/view_helper.rb +63 -0
- data/lib/search_fu.rb +4 -0
- data/search_fu.gemspec +25 -0
- data/spec/filter_fu_spec.rb +43 -0
- data/spec/schema.rb +32 -0
- data/spec/search_fu_spec.rb +90 -0
- data/spec/spec_helper.rb +34 -0
- metadata +108 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
data/filter_fu.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "filter_fu/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "filter_fu"
|
7
|
+
s.version = FilterFu::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Tan Kwang How"]
|
10
|
+
s.email = ["tankwanghow@gmail.com"]
|
11
|
+
s.homepage = "http://github.com/tankwanghow"
|
12
|
+
s.summary = %q{Combine query in views}
|
13
|
+
s.description = %q{A ActiveRecord method to allow user specify and combine query in views}
|
14
|
+
|
15
|
+
s.rubyforge_project = "filter_fu"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
s.add_development_dependency "sqlite3-ruby"
|
24
|
+
s.add_development_dependency "rails"
|
25
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
jQuery(function(){
|
2
|
+
//app.setupAjaxCallbacks();
|
3
|
+
});
|
4
|
+
|
5
|
+
var add_remove_row = {
|
6
|
+
bindRemoveLink: function(removeLinkClass, removeElementClass) {
|
7
|
+
$(removeLinkClass).live('click',
|
8
|
+
function(){
|
9
|
+
$(this).parents(removeElementClass).remove();
|
10
|
+
return false;
|
11
|
+
});
|
12
|
+
},
|
13
|
+
bindAddLink: function(addLinkElement, addHtml, appendAt) {
|
14
|
+
$(addLinkElement).click(function(){
|
15
|
+
html = $(addHtml).html().replace(/_NEW_/g, 'new_' + new Date().getTime());
|
16
|
+
$(appendAt).append(html);
|
17
|
+
return false;
|
18
|
+
});
|
19
|
+
}
|
20
|
+
};
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Filterable
|
2
|
+
module ControllerAdditions
|
3
|
+
def store_filterable_session
|
4
|
+
session["#{self.class.name.sub(/Controller/, '').underscore.singularize}_filterable"] = params[:filterable] if params[:filterable_commit]
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
if defined?(ActionController::Base)
|
10
|
+
ActionController::Base.send :include, Filterable::ControllerAdditions
|
11
|
+
end
|
12
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module FilterFu
|
2
|
+
module ModelAdditions
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
base.class_eval do
|
6
|
+
class_attribute :_filter_fu_attributes
|
7
|
+
self._filter_fu_attributes = []
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
def filter_fu(*args)
|
13
|
+
args.each do |attr|
|
14
|
+
c_attr = create_filter_fu_attribute_hash(attr)
|
15
|
+
self._filter_fu_attributes << c_attr unless self._filter_fu_attributes.detect { |t| t[:name] == c_attr[:name]}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def create_filter_fu_attribute_hash(attr)
|
22
|
+
raise "Parameter has no :name key" unless attr[:name]
|
23
|
+
raise "Parameter has no :where key" unless attr[:where]
|
24
|
+
{ name: attr[:name],
|
25
|
+
where: attr[:where],
|
26
|
+
operator: attr[:operator] || :eq,
|
27
|
+
convert: attr[:convert],
|
28
|
+
joins: attr[:joins],
|
29
|
+
and: attr[:and] }
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
if defined?(ActiveRecord::Base)
|
38
|
+
ActiveRecord::Base.send :include, FilterFu::ModelAdditions
|
39
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'action_view'
|
2
|
+
|
3
|
+
module FilterFu
|
4
|
+
module ViewHelper
|
5
|
+
def filter_fu_form_for(model_klass, options={})
|
6
|
+
hidden_filter_fields(model_klass) +
|
7
|
+
form_tag(polymorphic_path(Payment), options.merge(method: :get, id: 'filter_fu_form')) do
|
8
|
+
filter_table model_klass
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def filter_table(model_klass)
|
13
|
+
content_tag(:table, :id => 'filter_fu_table') do
|
14
|
+
content_tag(:thead, filter_header, :id => "filter_fu_thead") +
|
15
|
+
content_tag(:tbody, render_fields(model_klass),:id => "filter_fu_tbody") +
|
16
|
+
content_tag(:tfoot, filter_footer, :id => "filter_fu_tfoot")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def render_fields(model_klass)
|
21
|
+
html = ""
|
22
|
+
(session["#{model_klass.name.underscore}_filter_fu"] || params[:filter_fu] || {}).each do |k,v|
|
23
|
+
rand_id = (DateTime.now.to_i * rand * 100).to_i
|
24
|
+
html << content_tag(:tr, :id => "filter_fu_row_new_#{rand_id}", :class => "filter_fu_rows") do
|
25
|
+
content_tag(:td, select_tag("filter_fu[_new_#{rand_id}][name]", options_for_select(model_klass.filter_fu_names, v[:name]))) +
|
26
|
+
content_tag(:td, text_field_tag("filter_fu[_new_#{rand_id}][value]", v[:value])) +
|
27
|
+
content_tag(:td, link_to("X", "#", :class => 'filter_fu_remove'))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
html.html_safe
|
31
|
+
end
|
32
|
+
|
33
|
+
def filter_header
|
34
|
+
content_tag(:tr) do
|
35
|
+
content_tag(:td, "Filter") +
|
36
|
+
content_tag(:td, "Value", :colspan => 2)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def filter_footer
|
41
|
+
content_tag(:tr) do
|
42
|
+
content_tag(:td, link_to("Add", "#", :id => "filter_fu_add") + submit_tag("Apply", :name => "filter_fu_commit"), :colspan => 3)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def hidden_filter_fields(model_klass)
|
47
|
+
content_tag(:table, :style=>"display:none") do
|
48
|
+
content_tag(:tbody, :id => "hidden_filter_fields") do
|
49
|
+
content_tag(:tr, :id => "filter_fu_row_NEW_", :class => "filter_fu_rows") do
|
50
|
+
content_tag(:td, select_tag("filter_fu[_NEW_][name]", options_for_select(model_klass.filter_fu_names))) +
|
51
|
+
content_tag(:td, text_field_tag("filter_fu[_NEW_][value]")) +
|
52
|
+
content_tag(:td, link_to("X", "#", :class => 'filter_fu_remove'))
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
if defined?(ActionController::Base)
|
61
|
+
ActionController::Base.helper(FilterFu::ViewHelper)
|
62
|
+
end
|
63
|
+
|
data/lib/filter_fu.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
module SearchFu
|
2
|
+
module ControllerAdditions
|
3
|
+
def store_search_fu_session
|
4
|
+
session["#{self.class.name.sub(/Controller/, '').underscore.singularize}_search_fu"] = params[:search_fu] if params[:search_fu_commit]
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
if defined?(ActionController::Base)
|
10
|
+
ActionController::Base.send :include, SearchFu::ControllerAdditions
|
11
|
+
end
|
12
|
+
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module SearchFu
|
2
|
+
module ModelAdditions
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
base.class_eval do
|
6
|
+
class_attribute :_search_fu_attributes
|
7
|
+
self._search_fu_attributes = []
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
def filter(hash)
|
13
|
+
@rel = []
|
14
|
+
hash.each do |k,v|
|
15
|
+
search_fu_attr = self._search_fu_attributes.detect { |t| t[:name] == v[:name]}
|
16
|
+
raise "Column '#{v[:name]}' not found." unless search_fu_attr
|
17
|
+
@rel << generate_where(search_fu_attr, v[:value])
|
18
|
+
end
|
19
|
+
self.instance_eval(@rel.join('.'))
|
20
|
+
end
|
21
|
+
|
22
|
+
def filter_names
|
23
|
+
a = []
|
24
|
+
self._search_fu_attributes.each do |h|
|
25
|
+
a << h[:name]
|
26
|
+
end
|
27
|
+
a
|
28
|
+
end
|
29
|
+
|
30
|
+
def search_fu(name, hash)
|
31
|
+
c_attr = create_search_fu_attribute_hash(name, hash)
|
32
|
+
self._search_fu_attributes << c_attr unless self._search_fu_attributes.detect { |t| t[:name] == c_attr[:name]}
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def generate_where(attr, value)
|
38
|
+
a = grab_operator_value(value)
|
39
|
+
op = a[0] || attr[:operator]
|
40
|
+
val = attr[:convert].call(op, a[1]) if attr[:convert]
|
41
|
+
w = attr[:ar_query]
|
42
|
+
w.gsub(/<op>/, op).gsub(/<value>/, val.to_s)
|
43
|
+
end
|
44
|
+
|
45
|
+
def grab_operator_value(value)
|
46
|
+
a = value.split(' ')
|
47
|
+
operator = to_arel_operator(a[0])
|
48
|
+
a.delete_at(0) if operator
|
49
|
+
[operator, a.join(' ')]
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_arel_operator(val)
|
53
|
+
{"~" => "like", "=" => "=", ">=" => ">=", "<=" => "<=", "<" => "<", ">" => ">"}[val]
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_search_fu_attribute_hash(name, hash)
|
57
|
+
raise "No Query Key found in query hash" unless hash[:ar_query]
|
58
|
+
{
|
59
|
+
name: name,
|
60
|
+
ar_query: hash[:ar_query],
|
61
|
+
operator: hash[:operator] || '=',
|
62
|
+
convert: hash[:convert]
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
if defined?(ActiveRecord::Base)
|
71
|
+
ActiveRecord::Base.send :include, SearchFu::ModelAdditions
|
72
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'action_view'
|
2
|
+
|
3
|
+
module FilterFu
|
4
|
+
module ViewHelper
|
5
|
+
def search_fu_form_for(model_klass, options={})
|
6
|
+
hidden_filter_fields(model_klass) +
|
7
|
+
form_tag(polymorphic_path(Payment), options.merge(method: :get, id: 'search_fu_form')) do
|
8
|
+
filter_table model_klass
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def filter_table(model_klass)
|
13
|
+
content_tag(:table, :id => 'search_fu_table') do
|
14
|
+
content_tag(:thead, filter_header, :id => "search_fu_thead") +
|
15
|
+
content_tag(:tbody, render_fields(model_klass),:id => "search_fu_tbody") +
|
16
|
+
content_tag(:tfoot, filter_footer, :id => "search_fu_tfoot")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def render_fields(model_klass)
|
21
|
+
html = ""
|
22
|
+
(session["#{model_klass.name.underscore}_search_fu"] || params[:search_fu] || {}).each do |k,v|
|
23
|
+
rand_id = (DateTime.now.to_i * rand * 100).to_i
|
24
|
+
html << content_tag(:tr, :id => "search_fu_row_new_#{rand_id}", :class => "search_fu_rows") do
|
25
|
+
content_tag(:td, select_tag("search_fu[_new_#{rand_id}][name]", options_for_select(model_klass.search_fu_names, v[:name]))) +
|
26
|
+
content_tag(:td, text_field_tag("search_fu[_new_#{rand_id}][value]", v[:value])) +
|
27
|
+
content_tag(:td, link_to("X", "#", :class => 'search_fu_remove'))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
html.html_safe
|
31
|
+
end
|
32
|
+
|
33
|
+
def filter_header
|
34
|
+
content_tag(:tr) do
|
35
|
+
content_tag(:td, "Filter") +
|
36
|
+
content_tag(:td, "Value", :colspan => 2)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def filter_footer
|
41
|
+
content_tag(:tr) do
|
42
|
+
content_tag(:td, link_to("Add", "#", :id => "search_fu_add") + submit_tag("Apply", :name => "search_fu_commit"), :colspan => 3)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def hidden_filter_fields(model_klass)
|
47
|
+
content_tag(:table, :style=>"display:none") do
|
48
|
+
content_tag(:tbody, :id => "hidden_filter_fields") do
|
49
|
+
content_tag(:tr, :id => "search_fu_row_NEW_", :class => "search_fu_rows") do
|
50
|
+
content_tag(:td, select_tag("search_fu[_NEW_][name]", options_for_select(model_klass.search_fu_names))) +
|
51
|
+
content_tag(:td, text_field_tag("search_fu[_NEW_][value]")) +
|
52
|
+
content_tag(:td, link_to("X", "#", :class => 'search_fu_remove'))
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
if defined?(ActionController::Base)
|
61
|
+
ActionController::Base.helper(FilterFu::ViewHelper)
|
62
|
+
end
|
63
|
+
|
data/lib/search_fu.rb
ADDED
data/search_fu.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "search_fu/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "search_fu"
|
7
|
+
s.version = SearchFu::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Tan Kwang How"]
|
10
|
+
s.email = ["tankwanghow@gmail.com"]
|
11
|
+
s.homepage = "http://github.com/tankwanghow"
|
12
|
+
s.summary = %q{Combine query in views}
|
13
|
+
s.description = %q{A ActiveRecord method to allow user specify and combine query in views}
|
14
|
+
|
15
|
+
s.rubyforge_project = "search_fu"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
s.add_development_dependency "sqlite3-ruby"
|
24
|
+
s.add_development_dependency "rails"
|
25
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe FilterFu do
|
4
|
+
before(:each) {
|
5
|
+
Payment._filter_fu_attributes = []
|
6
|
+
@name_err_attr = { where: 'haha', operator: 'like' },
|
7
|
+
{ name: 'Date', where: "date", operator: '=',
|
8
|
+
value_proc: Proc.new { |val| Date.parse(val) } }
|
9
|
+
|
10
|
+
@where_err_attr = { name: 'haha', operator: 'like' },
|
11
|
+
{ name: 'Date', where: "date", operator: '=',
|
12
|
+
value_proc: Proc.new { |val| Date.parse(val) } }
|
13
|
+
|
14
|
+
|
15
|
+
@pay_attr1 = { name: 'Date', where: "date", operator: '=',
|
16
|
+
value_proc: Proc.new { |val| Date.parse(val) } },
|
17
|
+
{ name: 'Collector', where: 'collector', operator: 'like' }
|
18
|
+
}
|
19
|
+
it "should respond_to #filter_fu" do
|
20
|
+
Payment.respond_to?(:filter_fu).should be_true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should add #filter_fu params to _filter_fu_attributes" do
|
24
|
+
Payment.filter_fu(*@pay_attr1)
|
25
|
+
Payment._filter_fu_attributes.count.should == 2
|
26
|
+
end
|
27
|
+
|
28
|
+
it "#filter_fu should not duplicated :name attr to _filter_fu_attributes" do
|
29
|
+
Payment.filter_fu(*@pay_attr1)
|
30
|
+
Payment.filter_fu(*@pay_attr1)
|
31
|
+
Payment._filter_fu_attributes.count.should == 2
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should raise error, if #filter_fu params has no name key" do
|
35
|
+
lambda { Payment.filter_fu(*@name_err_attr) }.should raise_error "Parameter has no :name key"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should raise error, if #filter_fu params has no where key" do
|
39
|
+
lambda { Payment.filter_fu(*@where_err_attr) }.should raise_error "Parameter has no :where key"
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
end
|
data/spec/schema.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
ActiveRecord::Schema.define do
|
2
|
+
|
3
|
+
create_table "accounts", :force => true do |t|
|
4
|
+
t.string "name1", :null => false
|
5
|
+
t.string "name2"
|
6
|
+
t.integer "institution_id", :null => false
|
7
|
+
t.string "account_type_id", :null => false
|
8
|
+
t.text "description"
|
9
|
+
t.string "status", :default => "Active"
|
10
|
+
t.integer "lock_version"
|
11
|
+
end
|
12
|
+
|
13
|
+
create_table "payments", :force => true do |t|
|
14
|
+
t.integer "institution_id"
|
15
|
+
t.date "date"
|
16
|
+
t.string "collector"
|
17
|
+
t.integer "to_account_id"
|
18
|
+
t.integer "from_account_id"
|
19
|
+
t.string "cheque_no"
|
20
|
+
t.date "cheque_date"
|
21
|
+
t.string "currency"
|
22
|
+
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
|
+
t.text "note"
|
27
|
+
t.string "status"
|
28
|
+
t.integer "lock_version", :default => 0
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe FilterFu do
|
4
|
+
before(:each) {
|
5
|
+
Payment._search_fu_attributes = []
|
6
|
+
@err_attr2 = ['Error', { operator: '=' }]
|
7
|
+
@pay_attr1 = ['Collector', { ar_query: %q(where("payments.collector <op> '<value>'")), operator: 'like',
|
8
|
+
convert: Proc.new{|op,t| op == "like" ? "%#{t.to_s}%" : t.to_s}}]
|
9
|
+
@pay_attr2 = ['Pay to', { ar_query: %q(where("accounts.name1 <op> '<value>' or accounts.name2 <op> '<value>'").joins(:to_account)),
|
10
|
+
operator: 'like' , convert: Proc.new{|op,t| op == "like" ? "%#{t.to_s}%" : t.to_s}}]
|
11
|
+
@pay_attr3 = ['Pay from', { ar_query: %q(where("accounts.name1 <op> '<value>' or accounts.name2 <op> '<value>'").joins(:from_account)),
|
12
|
+
operator: 'like' , convert: Proc.new{|op,t| op == "like" ? "%#{t.to_s}%" : t.to_s}}]
|
13
|
+
@pay_attr4 = ['Date', { ar_query: %q(where("payments.date <op> '<value>'")),
|
14
|
+
operator: '=', convert: Proc.new {|op, t| Date.parse(t.to_s) } } ]
|
15
|
+
}
|
16
|
+
|
17
|
+
describe "#filter" do
|
18
|
+
before(:each) do
|
19
|
+
Payment.search_fu @pay_attr1[0], @pay_attr1[1]
|
20
|
+
Payment.search_fu @pay_attr2[0], @pay_attr2[1]
|
21
|
+
Payment.search_fu @pay_attr3[0], @pay_attr3[1]
|
22
|
+
Payment.search_fu @pay_attr4[0], @pay_attr4[1]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should return an array of names" do
|
26
|
+
Payment.filter_names.sort.should == ['Collector', 'Date', 'Pay from', 'Pay to']
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should combine where relation" do
|
30
|
+
Payment.filter( { b: { name: 'Pay to', value: 'smith' } , a: { name: 'Pay from', value: 'tkh'} }).to_sql.downcase.should ==
|
31
|
+
Payment.where("accounts.name1 like '%smith%' or accounts.name2 like '%smith%'").joins(:to_account).
|
32
|
+
where("accounts.name1 like '%tkh%' or accounts.name2 like '%tkh%'").joins(:from_account).to_sql.downcase
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should return join where relation" do
|
36
|
+
Payment.filter( { b: { name: 'Pay to', value: 'smith' } }).to_sql.downcase.should ==
|
37
|
+
Payment.where("accounts.name1 like '%smith%' or accounts.name2 like '%smith%'").joins(:to_account).to_sql.downcase
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should use value operator return simple where relation and convert value" do
|
41
|
+
Payment.filter( { b: { name: 'Date', value: '>= 12-Jun-2010' } }).to_sql.downcase.should ==
|
42
|
+
Payment.where('payments.date >= ?', Date.parse('12-Jun-2010')).to_sql.downcase
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return simple where relation and convert value" do
|
46
|
+
Payment.filter( { b: { name: 'Date', value: '12-Jun-2010' } }).to_sql.downcase.should ==
|
47
|
+
Payment.where("payments.date = '#{Date.parse('12-Jun-2010')}'").to_sql.downcase
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should use value operator and return simple where relation" do
|
51
|
+
Payment.filter({a: { name: 'Collector', value: '= smith ma'}}).to_sql.downcase.should ==
|
52
|
+
Payment.where("payments.collector = 'smith ma'").to_sql.downcase
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should return simple where relation" do
|
56
|
+
Payment.filter({a: { name: 'Collector', value: 'smith ma'}}).to_sql.downcase.should ==
|
57
|
+
Payment.where('payments.collector like ?', '%smith ma%').to_sql.downcase
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should raise error, if :name ont found" do
|
61
|
+
lambda { Payment.filter({a: { name: 'haha', value: 'mama'}}) }.should raise_error("Column 'haha' not found.")
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should respond_to #filter" do
|
67
|
+
Payment.respond_to?(:filter).should be_true
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should respond_to #search_fu" do
|
71
|
+
Payment.respond_to?(:search_fu).should be_true
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should add #search_fu params to _search_fu_attributes" do
|
75
|
+
Payment.search_fu(@pay_attr1[0], @pay_attr1[1])
|
76
|
+
Payment.search_fu(@pay_attr2[0], @pay_attr2[1])
|
77
|
+
Payment._search_fu_attributes.count.should == 2
|
78
|
+
end
|
79
|
+
|
80
|
+
it "#search_fu should not duplicated :name attr to _search_fu_attributes" do
|
81
|
+
Payment.search_fu(@pay_attr1[0], @pay_attr1[1])
|
82
|
+
Payment.search_fu(@pay_attr1[0], @pay_attr1[1])
|
83
|
+
Payment._search_fu_attributes.count.should == 1
|
84
|
+
end
|
85
|
+
|
86
|
+
it "#search_fu should raise error if :ar_query in nil" do
|
87
|
+
lambda { Payment.search_fu(@err_attr2[0], @err_attr2[1]) }.should raise_error "No Query Key found in query hash"
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_record'
|
3
|
+
require 'search_fu'
|
4
|
+
|
5
|
+
ActiveRecord::Base.establish_connection(
|
6
|
+
:adapter => 'sqlite3',
|
7
|
+
:database => ':memory:'
|
8
|
+
)
|
9
|
+
|
10
|
+
ActiveRecord::Base.silence do
|
11
|
+
ActiveRecord::Migration.verbose = false
|
12
|
+
load File.join('schema.rb')
|
13
|
+
end
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
config.mock_with :rspec
|
17
|
+
config.before(:each) do
|
18
|
+
Payment.delete_all
|
19
|
+
Account.delete_all
|
20
|
+
end
|
21
|
+
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
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: search_fu
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Tan Kwang How
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-02-16 00:00:00 +08:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rspec
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "0"
|
25
|
+
type: :development
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sqlite3-ruby
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: "0"
|
36
|
+
type: :development
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: rails
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id003
|
49
|
+
description: A ActiveRecord method to allow user specify and combine query in views
|
50
|
+
email:
|
51
|
+
- tankwanghow@gmail.com
|
52
|
+
executables: []
|
53
|
+
|
54
|
+
extensions: []
|
55
|
+
|
56
|
+
extra_rdoc_files: []
|
57
|
+
|
58
|
+
files:
|
59
|
+
- .gitignore
|
60
|
+
- Gemfile
|
61
|
+
- Rakefile
|
62
|
+
- filter_fu.gemspec
|
63
|
+
- javascript/add_remove_row.js
|
64
|
+
- lib/filter_fu.rb
|
65
|
+
- lib/filter_fu/controller_additions.rb
|
66
|
+
- lib/filter_fu/model_additions.rb
|
67
|
+
- lib/filter_fu/version.rb
|
68
|
+
- lib/filter_fu/view_helper.rb
|
69
|
+
- lib/search_fu.rb
|
70
|
+
- lib/search_fu/controller_additions.rb
|
71
|
+
- lib/search_fu/model_additions.rb
|
72
|
+
- lib/search_fu/version.rb
|
73
|
+
- lib/search_fu/view_helper.rb
|
74
|
+
- search_fu.gemspec
|
75
|
+
- spec/filter_fu_spec.rb
|
76
|
+
- spec/schema.rb
|
77
|
+
- spec/search_fu_spec.rb
|
78
|
+
- spec/spec_helper.rb
|
79
|
+
has_rdoc: true
|
80
|
+
homepage: http://github.com/tankwanghow
|
81
|
+
licenses: []
|
82
|
+
|
83
|
+
post_install_message:
|
84
|
+
rdoc_options: []
|
85
|
+
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: "0"
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: "0"
|
100
|
+
requirements: []
|
101
|
+
|
102
|
+
rubyforge_project: search_fu
|
103
|
+
rubygems_version: 1.5.2
|
104
|
+
signing_key:
|
105
|
+
specification_version: 3
|
106
|
+
summary: Combine query in views
|
107
|
+
test_files: []
|
108
|
+
|