searchgasm 1.3.3 → 1.3.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,10 @@
1
+ == 1.3.4 released 2008-10-03
2
+
3
+ * Fixed method names creation for conditions with modifiers
4
+ * Create local column conditions, incase there are method conflicts. Such as "id".
5
+ * All joins are switched to left outer joins. When search with *any* conditions, inner joins return incorrect results. Also when ordering by an association that allows for blanks, inner joins exclude the records with blank values. Only option is left outer joins.
6
+ * If joins is manually set with a string, treat it as SQL, just like ActiveRecord
7
+
1
8
  == 1.3.3 released 2008-10-03
2
9
 
3
10
  * Fixed modifiers being double escaped on equals condition
@@ -11,7 +11,7 @@ module Searchgasm
11
11
  attr_accessor :any, :relationship_name
12
12
 
13
13
  class << self
14
- attr_accessor :added_klass_conditions, :added_column_conditions, :added_associations
14
+ attr_accessor :added_klass_conditions, :added_column_equals_conditions, :added_associations
15
15
 
16
16
  def column_details # :nodoc:
17
17
  return @column_details if @column_details
@@ -149,6 +149,7 @@ module Searchgasm
149
149
 
150
150
  def initialize(init_conditions = {})
151
151
  add_associations!
152
+ add_column_equals_conditions!
152
153
  self.conditions = init_conditions
153
154
  end
154
155
 
@@ -266,6 +267,12 @@ module Searchgasm
266
267
  self.class.added_associations = true
267
268
  end
268
269
 
270
+ def add_column_equals_conditions!
271
+ return true if self.class.added_column_equals_conditions
272
+ klass.column_names.each { |name| setup_condition(name) }
273
+ self.class.added_column_equals_conditions = true
274
+ end
275
+
269
276
  def extract_column_and_condition_from_method_name(name)
270
277
  name_parts = name.gsub("=", "").split("_")
271
278
 
@@ -334,42 +341,56 @@ module Searchgasm
334
341
  modifier_name_parts = []
335
342
  modifier_klasses.each { |modifier_klass| modifier_name_parts << modifier_klass.modifier_names.first }
336
343
  method_name_parts = []
337
- method_name_parts << modifier_name_parts.join("_of_") unless modifier_name_parts.blank?
344
+ method_name_parts << modifier_name_parts.join("_of_") + "_of" unless modifier_name_parts.blank?
338
345
  method_name_parts << column_name
339
- method_name_parts << condition_name
346
+ method_name_parts << condition_name unless condition_name.blank?
340
347
  method_name_parts.join("_")
341
348
  end
342
349
 
343
350
  def method_missing(name, *args, &block)
351
+ if setup_condition(name)
352
+ send(name, *args, &block)
353
+ else
354
+ super
355
+ end
356
+ end
357
+
358
+ def setup_condition(name)
344
359
  modifier_klasses, column_detail, condition_klass = breakdown_method_name(name.to_s)
345
360
  if !column_detail.nil? && !condition_klass.nil?
346
361
  method_name = build_method_name(modifier_klasses, column_detail[:column].name, condition_klass.condition_names_for_column.first)
347
- column_type = column_sql = nil
348
- if !modifier_klasses.blank?
349
- # Find the column type
350
- column_type = modifier_klasses.first.return_type
362
+
363
+ if !added_condition?(method_name)
364
+ column_type = column_sql = nil
365
+ if !modifier_klasses.blank?
366
+ # Find the column type
367
+ column_type = modifier_klasses.first.return_type
351
368
 
352
- # Build the column sql
353
- column_sql = "#{klass.connection.quote_table_name(klass.table_name)}.#{klass.connection.quote_column_name(column_detail[:column].name)}"
354
- modifier_klasses.each do |modifier_klass|
355
- next unless klass.connection.respond_to?(modifier_klass.adapter_method_name)
356
- column_sql = klass.connection.send(modifier_klass.adapter_method_name, column_sql)
369
+ # Build the column sql
370
+ column_sql = "#{klass.connection.quote_table_name(klass.table_name)}.#{klass.connection.quote_column_name(column_detail[:column].name)}"
371
+ modifier_klasses.each do |modifier_klass|
372
+ next unless klass.connection.respond_to?(modifier_klass.adapter_method_name)
373
+ column_sql = klass.connection.send(modifier_klass.adapter_method_name, column_sql)
374
+ end
357
375
  end
358
- end
359
376
 
360
- add_condition!(condition_klass, method_name, column_detail[:column], column_type, column_sql)
377
+ add_condition!(condition_klass, method_name, column_detail[:column], column_type, column_sql)
361
378
 
362
- ([column_detail[:column].name] + column_detail[:aliases]).each do |column_name|
363
- condition_klass.condition_names_for_column.each do |condition_name|
364
- alias_method_name = build_method_name(modifier_klasses, column_name, condition_name)
365
- add_condition_alias!(alias_method_name, method_name) unless alias_method_name == method_name
379
+ ([column_detail[:column].name] + column_detail[:aliases]).each do |column_name|
380
+ condition_klass.condition_names_for_column.each do |condition_name|
381
+ alias_method_name = build_method_name(modifier_klasses, column_name, condition_name)
382
+ add_condition_alias!(alias_method_name, method_name) unless added_condition?(alias_method_name)
383
+ end
366
384
  end
367
385
  end
368
386
 
369
- send(method_name + (name.to_s =~ /=$/ ? "=" : ""), *args, &block)
370
- else
371
- super
387
+ alias_method_name = name.to_s.gsub("=", "")
388
+ add_condition_alias!(alias_method_name, method_name) unless added_condition?(alias_method_name)
389
+
390
+ return true
372
391
  end
392
+
393
+ false
373
394
  end
374
395
 
375
396
  def add_condition!(condition, name, column = nil, column_type = nil, column_sql = nil)
@@ -397,6 +418,10 @@ module Searchgasm
397
418
  end_eval
398
419
  end
399
420
 
421
+ def added_condition?(name)
422
+ respond_to?("#{name}_object") && respond_to?(name) && respond_to?("#{name}=") && respond_to?("reset_#{name}!")
423
+ end
424
+
400
425
  def add_condition_alias!(alias_name, name)
401
426
  self.class.condition_names << alias_name
402
427
 
@@ -84,6 +84,7 @@ module Searchgasm
84
84
  # * <tt>:params</tt> -- default: nil, Additional params to add to the url, must be a hash
85
85
  # * <tt>:exclude_params</tt> -- default: nil, params you want to exclude. This is nifty because it does a "deep delete". So you can pass {:param1 => {:param2 => :param3}} and it will make sure param3 does not get include. param1 and param2 will not be touched. This also accepts an array or just a symbol or string.
86
86
  # * <tt>:search_params</tt> -- default: nil, Additional search params to add to the url, must be a hash. Adds the options into the :params_scope.
87
+ # * <tt>:literal_search_params</tt> -- default: nil, Additional search params to add to the url, but are not escaped. So you can add javascript into the URL: :literal_search_params => {:per_page => "' + escape(this.value) + '"}
87
88
  # * <tt>:exclude_search_params</tt> -- default: nil, Same as :exclude_params but for the :search_params.
88
89
  def searchgasm_url(options = {})
89
90
  search_params = searchgasm_params(options)
@@ -79,8 +79,27 @@ module Searchgasm #:nodoc:
79
79
  "#<#{klass}Search #{current_find_options.inspect}>"
80
80
  end
81
81
 
82
+ # Searchgasm requires that all joins be left outer joins for conditions and ordering to work properly
82
83
  def joins
83
- merge_joins(@joins, auto_joins)
84
+ joins_sql = ""
85
+ all_joins = auto_joins
86
+
87
+ case @joins
88
+ when String
89
+ joins_sql += @joins
90
+ else
91
+ all_joins = merge_joins(@joins, all_joins)
92
+ end
93
+
94
+ return if joins_sql.blank? && all_joins.blank?
95
+
96
+ unless all_joins.blank?
97
+ join_dependency = ::ActiveRecord::Associations::ClassMethods::JoinDependency.new(klass, all_joins, nil)
98
+ joins_sql += " " unless joins_sql.blank?
99
+ joins_sql += join_dependency.join_associations.collect { |assoc| assoc.association_join }.join
100
+ end
101
+
102
+ joins_sql
84
103
  end
85
104
 
86
105
  def limit=(value)
@@ -11,7 +11,6 @@ module Searchgasm
11
11
  alias_method_chain :conditions=, :conditions
12
12
  alias_method_chain :conditions, :conditions
13
13
  alias_method_chain :auto_joins, :conditions
14
- alias_method_chain :joins, :conditions
15
14
  alias_method_chain :sanitize, :conditions
16
15
  end
17
16
  end
@@ -57,16 +56,6 @@ module Searchgasm
57
56
  @memoized_auto_joins ||= merge_joins(auto_joins_without_conditions, conditions.auto_joins)
58
57
  end
59
58
 
60
- # Changes joins to use left outer joins if conditions.any == true.
61
- def joins_with_conditions
62
- if conditions.any?
63
- join_dependency = ::ActiveRecord::Associations::ClassMethods::JoinDependency.new(klass, joins_without_conditions, nil)
64
- join_dependency.join_associations.collect { |assoc| assoc.association_join }.join
65
- else
66
- joins_without_conditions
67
- end
68
- end
69
-
70
59
  def sanitize_with_conditions(searching = true) # :nodoc:
71
60
  find_options = sanitize_without_conditions(searching)
72
61
  if conditions_obj = find_options.delete(:conditions)
@@ -67,7 +67,7 @@ module Searchgasm
67
67
 
68
68
  MAJOR = 1
69
69
  MINOR = 3
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,18 +1,18 @@
1
1
 
2
- # Gem::Specification for Searchgasm-1.3.3
2
+ # Gem::Specification for Searchgasm-1.3.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.3.3
8
+ version: 1.3.4
9
9
  platform: ruby
10
10
  authors:
11
11
  - Ben Johnson of Binary Logic
12
12
  autorequire:
13
13
  bindir: bin
14
14
 
15
- date: 2008-10-05 00:00:00 -04:00
15
+ date: 2008-10-07 00:00:00 -04:00
16
16
  default_executable:
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
@@ -24,4 +24,13 @@ jennifer:
24
24
  last_name: Hopkins
25
25
  active: false
26
26
  bio: Totally not awesome at all!
27
+
28
+ tren:
29
+ id: 4
30
+ account_id:
31
+ parent_id:
32
+ first_name: Tren
33
+ last_name: Garfield
34
+ active: false
35
+ bio: Rocks a little too hard
27
36
 
@@ -213,4 +213,9 @@ class TestConditionsBase < Test::Unit::TestCase
213
213
  conditions.reset_users!
214
214
  assert_equal({}, conditions.send(:objects))
215
215
  end
216
+
217
+ def test_method_conflicts
218
+ conditions = Searchgasm::Cache::AccountConditions.new
219
+ assert_equal nil, conditions.id
220
+ end
216
221
  end
@@ -28,9 +28,9 @@ class TestSearchBase < Test::Unit::TestCase
28
28
  end
29
29
 
30
30
  def test_setting_first_level_options
31
- search = Account.new_search!(:include => :users, :joins => :test, :offset => 5, :limit => 20, :order => "name ASC", :select => "name", :readonly => true, :group => "name", :from => "accounts", :lock => true)
31
+ search = Account.new_search!(:include => :users, :joins => :users, :offset => 5, :limit => 20, :order => "name ASC", :select => "name", :readonly => true, :group => "name", :from => "accounts", :lock => true)
32
32
  assert_equal :users, search.include
33
- assert_equal :test, search.joins
33
+ assert_equal " LEFT OUTER JOIN \"users\" ON users.account_id = accounts.id ", search.joins
34
34
  assert_equal 5, search.offset
35
35
  assert_equal 20, search.limit
36
36
  assert_equal "name ASC", search.order
@@ -44,9 +44,10 @@ class TestSearchBase < Test::Unit::TestCase
44
44
 
45
45
  search.include = :users
46
46
  assert_equal :users, search.include
47
-
48
- search.joins = "test"
49
- assert_equal "test", search.joins
47
+
48
+ # treat it like SQL, just like AR
49
+ search.joins = "users"
50
+ assert_equal "users", search.joins
50
51
 
51
52
  search.page = 5
52
53
  assert_equal 1, search.page
@@ -140,7 +141,7 @@ class TestSearchBase < Test::Unit::TestCase
140
141
  search.conditions.users.id_greater_than = 2
141
142
  search.page = 3
142
143
  search.readonly = true
143
- assert_equal({:joins => :users, :offset => 4, :readonly => true, :conditions => ["(\"accounts\".\"name\" LIKE ?) AND (\"users\".\"id\" > ?)", "%Binary%", 2], :limit => 2 }, search.sanitize)
144
+ assert_equal({:joins => " LEFT OUTER JOIN \"users\" ON users.account_id = accounts.id ", :offset => 4, :readonly => true, :conditions => ["(\"accounts\".\"name\" LIKE ?) AND (\"users\".\"id\" > ?)", "%Binary%", 2], :limit => 2 }, search.sanitize)
144
145
  end
145
146
 
146
147
  def test_scope
@@ -23,16 +23,6 @@ class TestSearchConditions < Test::Unit::TestCase
23
23
  assert_equal nil, search.auto_joins
24
24
  end
25
25
 
26
- def test_joins
27
- search = Account.new_search
28
- search.conditions = {:id_lte => 2, :users => {:first_name_like => "Ben"}}
29
- assert_equal :users, search.joins
30
- assert_equal [Account.find(1)], search.all
31
- search.conditions.any = true
32
- assert_equal " LEFT OUTER JOIN \"users\" ON users.account_id = accounts.id ", search.joins
33
- assert_equal Account.find(1, 2), search.all
34
- end
35
-
36
26
  def test_sanitize
37
27
  # This is tested in test_search_base
38
28
  end
@@ -157,4 +157,10 @@ class TestSearchOrdering < Test::Unit::TestCase
157
157
  def test_sanitize
158
158
  # tested in test_priority_order_by
159
159
  end
160
+
161
+ def test_ordering_includes_blank
162
+ search = User.new_search
163
+ search.order_by = {:account => :name}
164
+ assert_equal 4, search.count
165
+ end
160
166
  end
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.3.3
4
+ version: 1.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Johnson of Binary Logic
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-10-05 00:00:00 -04:00
12
+ date: 2008-10-07 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency