searchgasm 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,8 @@
1
+ == 1.0.4 released 2008-09-18
2
+
3
+ * Fixed bugs when performing calculations and searches on has_many through relationships.
4
+ * Instead of merging the find_options myself, I delegated that to AR's with_scope function, which already does this. Much more solid, less intrusive.
5
+
1
6
  == 1.0.3 released 2008-09-18
2
7
 
3
8
  * Updated inspect to show the current options for your search. Plays nicer in the console.
data/Manifest CHANGED
@@ -39,7 +39,6 @@ lib/searchgasm/search/conditions.rb
39
39
  lib/searchgasm/search/ordering.rb
40
40
  lib/searchgasm/search/pagination.rb
41
41
  lib/searchgasm/search/protection.rb
42
- lib/searchgasm/search/scoping.rb
43
42
  lib/searchgasm/search.rb
44
43
  lib/searchgasm/shared/searching.rb
45
44
  lib/searchgasm/shared/utilities.rb
data/README.rdoc CHANGED
@@ -147,7 +147,7 @@ Take the @search object and pass it right into form\_for or fields\_for (see abo
147
147
  Using the object from above:
148
148
 
149
149
  @search.average('id')
150
- @search.count
150
+ @search.count # ignores limit and offset
151
151
  @search.maximum('id')
152
152
  @search.minimum('id')
153
153
  @search.sum('id')
@@ -11,6 +11,12 @@ module Searchgasm
11
11
  calculate_without_searchgasm(*args)
12
12
  end
13
13
 
14
+ def total(*args)
15
+ options = args.extract_options!
16
+ searcher = searchgasm_searcher(options)
17
+ searcher.total
18
+ end
19
+
14
20
  # This is an alias method chain. It hooks into ActiveRecord's "find" method and checks to see if Searchgasm should get involved.
15
21
  def find_with_searchgasm(*args)
16
22
  options = args.extract_options!
@@ -126,40 +132,36 @@ module Searchgasm
126
132
  private
127
133
  def sanitize_options_with_searchgasm(options = {})
128
134
  return options unless Searchgasm::Search::Base.needed?(self, options)
129
- search = Searchgasm::Search::Base.create_virtual_class(self).new(options) # call explicitly to avoid merging the scopes into the searcher
135
+ search = Searchgasm::Search::Base.create_virtual_class(self).new # call explicitly to avoid merging the scopes into the searcher
130
136
  search.acting_as_filter = true
137
+ search.options = options
131
138
  search.sanitize
132
139
  end
133
140
 
134
141
  def searchgasm_conditions(options = {})
135
- conditions = Searchgasm::Conditions::Base.create_virtual_class(self).new(options)
136
- conditions.conditions = (scope(:find) || {})[:conditions]
137
- conditions
142
+ searcher = nil
143
+ conditions = nil
144
+ conditions = options.delete(:conditions) if options[:conditions].is_a?(Hash)
145
+
146
+ with_scope(:find => {:conditions => options[:conditions]}) do
147
+ searcher = Searchgasm::Conditions::Base.create_virtual_class(self).new(scope(:find)[:conditions])
148
+ searcher.conditions = conditions unless conditions.nil?
149
+ end
150
+
151
+ searcher
138
152
  end
139
153
 
140
154
  def searchgasm_searcher(options = {})
141
- search = Searchgasm::Search::Base.create_virtual_class(self).new(options)
142
- options_from_scope_for_searchgasm(options).each { |option, value| search.send("#{option}=", value) }
143
- search
144
- end
145
-
146
- def options_from_scope_for_searchgasm(options)
147
- # The goal here is to mimic how scope work. Merge what scopes would and don't what they wouldn't.
148
- scope = scope(:find) || {}
149
- scope_options = {}
150
- [:group, :include, :select, :readonly].each { |option| scope_options[option] = scope[option] if !options.has_key?(option) && scope.has_key?(option) }
155
+ searcher = nil
156
+ conditions = nil
157
+ conditions = options.delete(:conditions) if options[:conditions].is_a?(Hash)
151
158
 
152
- if scope[:joins] || options[:joins]
153
- scope_options[:joins] = []
154
- scope_options[:joins] += scope[:joins].is_a?(Array) ? scope[:joins] : [scope[:joins]] unless scope[:joins].blank?
155
- scope_options[:joins] += options[:joins].is_a?(Array) ? options[:joins] : [options[:joins]] unless options[:joins].blank?
159
+ with_scope(:find => options) do
160
+ searcher = Searchgasm::Search::Base.create_virtual_class(self).new(scope(:find))
161
+ searcher.conditions = conditions unless conditions.nil?
156
162
  end
157
163
 
158
- scope_options[:limit] = scope[:limit] if !options.has_key?(:per_page) && !options.has_key?(:limit) && scope.has_key?(:per_page)
159
- scope_options[:offset] = scope[:offset] if !options.has_key?(:page) && !options.has_key?(:offset) && scope.has_key?(:offset)
160
- scope_options[:order] = scope[:order] if !options.has_key?(:order_by) && !options.has_key?(:order) && scope.has_key?(:order)
161
- scope_options[:conditions] = scope[:conditions] if scope.has_key?(:conditions)
162
- scope_options
164
+ searcher
163
165
  end
164
166
  end
165
167
  end
@@ -83,17 +83,6 @@ module Searchgasm
83
83
  self.conditions = init_conditions
84
84
  end
85
85
 
86
- # Setup methods for searching
87
- [:all, :average, :calculate, :count, :find, :first, :maximum, :minimum, :sum].each do |method|
88
- class_eval <<-"end_eval", __FILE__, __LINE__
89
- def #{method}(*args)
90
- self.conditions = args.extract_options!
91
- args << {:conditions => sanitize}
92
- klass.#{method}(*args)
93
- end
94
- end_eval
95
- end
96
-
97
86
  # A list of includes to use when searching, includes relationships
98
87
  def includes
99
88
  i = []
@@ -112,11 +101,11 @@ module Searchgasm
112
101
  end
113
102
 
114
103
  # Sanitizes the conditions down into conditions that ActiveRecord::Base.find can understand.
115
- def sanitize(for_method = nil)
104
+ def sanitize(any = false)
116
105
  conditions = merge_conditions(*objects.collect { |object| object.sanitize })
117
106
  return sql if conditions.blank?
118
107
  merged_conditions = merge_conditions(conditions, sql)
119
- for_method.blank? ? merged_conditions : {:conditions => merged_conditions}
108
+ merged_conditions
120
109
  end
121
110
 
122
111
  # Allows you to set the conditions via a hash.
@@ -36,7 +36,7 @@ module Searchgasm #:nodoc:
36
36
  # Flag to determine if searchgasm is acting as a filter for the ActiveRecord search methods.
37
37
  # The purpose of this is to determine if Config.per_page should be implemented.
38
38
  def acting_as_filter=(value)
39
- @acting_as_filter == true
39
+ @acting_as_filter = value
40
40
  end
41
41
 
42
42
  # See acting_as_filter=
@@ -84,11 +84,11 @@ module Searchgasm #:nodoc:
84
84
  end
85
85
 
86
86
  # Sanitizes everything down into options ActiveRecord::Base.find can understand
87
- def sanitize(for_method = nil)
87
+ def sanitize
88
88
  find_options = {}
89
89
  ::ActiveRecord::Base.valid_find_options.each do |find_option|
90
90
  value = send(find_option)
91
- next if value.blank? || (for_method == :count && [:limit, :offset].include?(find_option))
91
+ next if value.blank?
92
92
  find_options[find_option] = value
93
93
  end
94
94
  find_options
@@ -51,8 +51,8 @@ module Searchgasm
51
51
  includes.blank? ? nil : (includes.size == 1 ? includes.first : includes)
52
52
  end
53
53
 
54
- def sanitize_with_conditions(for_method = nil) # :nodoc:
55
- find_options = sanitize_without_conditions(for_method)
54
+ def sanitize_with_conditions # :nodoc:
55
+ find_options = sanitize_without_conditions
56
56
  if conditions_obj = find_options.delete(:conditions)
57
57
  new_conditions = conditions_obj.sanitize
58
58
  find_options[:conditions] = new_conditions unless new_conditions.blank?
@@ -6,7 +6,8 @@ module Searchgasm
6
6
  # this module.
7
7
  module Searching
8
8
  # Use these methods just like you would in ActiveRecord
9
- SEARCH_METHODS = [:all, :average, :calculate, :count, :find, :first, :maximum, :minimum, :sum]
9
+ SEARCH_METHODS = [:all, :find, :first]
10
+ CALCULATION_METHODS = [:average, :calculate, :count, :maximum, :minimum, :sum]
10
11
 
11
12
  # Setup methods for searching
12
13
  SEARCH_METHODS.each do |method|
@@ -14,7 +15,22 @@ module Searchgasm
14
15
  def #{method}(*args)
15
16
  options = args.extract_options!
16
17
  klass.send(:with_scope, :find => options) do
17
- args << sanitize(:#{method})
18
+ args << (self.class < Searchgasm::Conditions::Base ? {:conditions => sanitize} : sanitize)
19
+ klass.#{method}(*args)
20
+ end
21
+ end
22
+ end_eval
23
+ end
24
+
25
+ # Setup methods for calculating
26
+ CALCULATION_METHODS.each do |method|
27
+ class_eval <<-"end_eval", __FILE__, __LINE__
28
+ def #{method}(*args)
29
+ options = args.extract_options!
30
+ klass.send(:with_scope, :find => options) do
31
+ find_options = (self.class < Searchgasm::Conditions::Base ? {:conditions => sanitize} : sanitize)
32
+ find_options.delete(:select)
33
+ args << find_options
18
34
  klass.#{method}(*args)
19
35
  end
20
36
  end
@@ -67,7 +67,7 @@ module Searchgasm
67
67
 
68
68
  MAJOR = 1
69
69
  MINOR = 0
70
- TINY = 3
70
+ TINY = 4
71
71
 
72
72
  # The current version as a Version instance
73
73
  CURRENT = new(MAJOR, MINOR, TINY)
data/searchgasm.gemspec CHANGED
@@ -1,11 +1,11 @@
1
1
 
2
- # Gem::Specification for Searchgasm-1.0.3
2
+ # Gem::Specification for Searchgasm-1.0.4
3
3
  # Originally generated by Echoe
4
4
 
5
5
  --- !ruby/object:Gem::Specification
6
6
  name: searchgasm
7
7
  version: !ruby/object:Gem::Version
8
- version: 1.0.3
8
+ version: 1.0.4
9
9
  platform: ruby
10
10
  authors:
11
11
  - Ben Johnson of Binary Logic
@@ -91,7 +91,6 @@ extra_rdoc_files:
91
91
  - lib/searchgasm/search/ordering.rb
92
92
  - lib/searchgasm/search/pagination.rb
93
93
  - lib/searchgasm/search/protection.rb
94
- - lib/searchgasm/search/scoping.rb
95
94
  - lib/searchgasm/search.rb
96
95
  - lib/searchgasm/shared/searching.rb
97
96
  - lib/searchgasm/shared/utilities.rb
@@ -141,7 +140,6 @@ files:
141
140
  - lib/searchgasm/search/ordering.rb
142
141
  - lib/searchgasm/search/pagination.rb
143
142
  - lib/searchgasm/search/protection.rb
144
- - lib/searchgasm/search/scoping.rb
145
143
  - lib/searchgasm/search.rb
146
144
  - lib/searchgasm/shared/searching.rb
147
145
  - lib/searchgasm/shared/utilities.rb
@@ -28,6 +28,10 @@ class TestActiveRecordAssociations < Test::Unit::TestCase
28
28
  assert_equal User.find(1), Account.find(1).users.first(:conditions => {:first_name_begins_with => "Ben"})
29
29
  assert_equal User.find(1), Account.find(1).users.find(:first, :conditions => {:first_name_begins_with => "Ben"})
30
30
  assert_equal [], Account.find(1).users.all(:conditions => {:first_name_begins_with => "Ben"}, :per_page => 20, :page => 5)
31
+
32
+ search = Account.find(1).users.new_search
33
+ assert_equal User.find(1, 3), search.all
34
+ assert_equal User.find(1), search.first
31
35
  end
32
36
 
33
37
  def test_calculations
@@ -43,13 +47,15 @@ class TestActiveRecordAssociations < Test::Unit::TestCase
43
47
  assert_equal 1, Account.find(1).orders.sum("id", :conditions => {:total_gt => 100})
44
48
  assert_equal 0, Account.find(1).orders.sum("id", :conditions => {:total_gt => 1000})
45
49
  assert_equal 1, Account.find(1).orders.average("id", :conditions => {:total_gt => 100})
50
+
51
+ search = Account.find(1).orders.new_search
52
+ assert_equal [Order.find(1)], search.all
53
+ assert_equal Order.find(1), search.first
54
+ assert_equal 1, search.average("id")
55
+ assert_equal 1, search.count
46
56
  end
47
57
 
48
58
  def test_habtm
49
59
 
50
60
  end
51
-
52
- def test_special_options
53
- #order, see AR doc, etc
54
- end
55
61
  end
@@ -80,4 +80,9 @@ class TestActiveRecordBase < Test::Unit::TestCase
80
80
  def test_scoping
81
81
  assert_equal nil, Account.send(:scope, :find)
82
82
  end
83
+
84
+ def test_count
85
+ assert_equal 3, Account.count
86
+ assert_equal 3, Account.count(:limit => 1)
87
+ end
83
88
  end
@@ -29,6 +29,14 @@ class TestSearchBase < Test::Unit::TestCase
29
29
  assert_equal 10, search.limit
30
30
  assert_equal true, search.readonly
31
31
  end
32
+
33
+ def test_acting_as_filter
34
+ search = Account.new_search
35
+ search.acting_as_filter = true
36
+ assert search.acting_as_filter?
37
+ search.acting_as_filter = false
38
+ assert !search.acting_as_filter?
39
+ end
32
40
 
33
41
  def test_setting_first_level_options
34
42
  search = Account.new_search
@@ -131,8 +139,7 @@ class TestSearchBase < Test::Unit::TestCase
131
139
  search.conditions.users.id_greater_than = 2
132
140
  search.page = 3
133
141
  search.readonly = true
134
- assert_equal({:include => :users, :offset => 4, :readonly => true, :conditions => ["(\"accounts\".\"name\" LIKE ?) AND (\"users\".\"id\" > ?)", "%Binary%", 2], :limit => 2 }, search.sanitize(:all))
135
- assert_equal({:include => :users, :readonly => true, :conditions => ["(\"accounts\".\"name\" LIKE ?) AND (\"users\".\"id\" > ?)", "%Binary%", 2] }, search.sanitize(:count))
142
+ assert_equal({:include => :users, :offset => 4, :readonly => true, :conditions => ["(\"accounts\".\"name\" LIKE ?) AND (\"users\".\"id\" > ?)", "%Binary%", 2], :limit => 2 }, search.sanitize)
136
143
  end
137
144
 
138
145
  def test_scope
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: searchgasm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Johnson of Binary Logic
@@ -88,7 +88,6 @@ extra_rdoc_files:
88
88
  - lib/searchgasm/search/ordering.rb
89
89
  - lib/searchgasm/search/pagination.rb
90
90
  - lib/searchgasm/search/protection.rb
91
- - lib/searchgasm/search/scoping.rb
92
91
  - lib/searchgasm/search.rb
93
92
  - lib/searchgasm/shared/searching.rb
94
93
  - lib/searchgasm/shared/utilities.rb
@@ -138,7 +137,6 @@ files:
138
137
  - lib/searchgasm/search/ordering.rb
139
138
  - lib/searchgasm/search/pagination.rb
140
139
  - lib/searchgasm/search/protection.rb
141
- - lib/searchgasm/search/scoping.rb
142
140
  - lib/searchgasm/search.rb
143
141
  - lib/searchgasm/shared/searching.rb
144
142
  - lib/searchgasm/shared/utilities.rb
File without changes