searchgasm 1.3.5 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +11 -0
- data/Manifest +12 -3
- data/README.rdoc +11 -0
- data/TODO.rdoc +4 -1
- data/lib/searchgasm/active_record/associations.rb +25 -14
- data/lib/searchgasm/active_record/base.rb +49 -0
- data/lib/searchgasm/active_record/connection_adapters/mysql_adapter.rb +20 -0
- data/lib/searchgasm/active_record/connection_adapters/postgresql_adapter.rb +20 -0
- data/lib/searchgasm/active_record/connection_adapters/sqlite_adapter.rb +21 -0
- data/lib/searchgasm/condition/base.rb +31 -10
- data/lib/searchgasm/condition/inclusive_descendant_of.rb +1 -1
- data/lib/searchgasm/condition/not_begin_with.rb +1 -1
- data/lib/searchgasm/condition/not_blank.rb +17 -0
- data/lib/searchgasm/condition/not_end_with.rb +1 -1
- data/lib/searchgasm/condition/not_equal.rb +1 -1
- data/lib/searchgasm/condition/not_have_keywords.rb +1 -1
- data/lib/searchgasm/condition/not_like.rb +1 -1
- data/lib/searchgasm/condition/not_nil.rb +17 -0
- data/lib/searchgasm/condition/sibling_of.rb +1 -1
- data/lib/searchgasm/conditions/base.rb +9 -7
- data/lib/searchgasm/conditions/protection.rb +1 -1
- data/lib/searchgasm/helpers/control_types/select.rb +1 -1
- data/lib/searchgasm/helpers/utilities.rb +1 -1
- data/lib/searchgasm/modifiers/lower.rb +15 -0
- data/lib/searchgasm/modifiers/ltrim.rb +15 -0
- data/lib/searchgasm/modifiers/rtrim.rb +15 -0
- data/lib/searchgasm/modifiers/trim.rb +15 -0
- data/lib/searchgasm/modifiers/upper.rb +15 -0
- data/lib/searchgasm/search/base.rb +44 -40
- data/lib/searchgasm/search/conditions.rb +0 -16
- data/lib/searchgasm/search/ordering.rb +0 -8
- data/lib/searchgasm/search/searching.rb +0 -6
- data/lib/searchgasm/version.rb +2 -2
- data/lib/searchgasm.rb +2 -2
- data/searchgasm.gemspec +22 -6
- data/test/fixtures/cats.yml +3 -0
- data/test/fixtures/dogs.yml +3 -0
- data/test/test_active_record_base.rb +4 -0
- data/test/test_condition_base.rb +4 -4
- data/test/test_condition_types.rb +27 -27
- data/test/test_conditions_base.rb +22 -1
- data/test/test_helper.rb +24 -5
- data/test/test_search_base.rb +12 -19
- data/test/test_search_conditions.rb +1 -11
- data/test/test_search_ordering.rb +3 -4
- data/{test/libs → test_libs}/acts_as_tree.rb +0 -0
- data/{test/libs → test_libs}/ordered_hash.rb +0 -0
- data/{test/libs → test_libs}/rexml_fix.rb +0 -0
- metadata +21 -5
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
== 1.4.0 released 2008-10-08
|
2
|
+
|
3
|
+
* Fixed bug when duping or cloning to copy over instance vars instead of method values
|
4
|
+
* Fixed bug with older versions of ActiveRecord and creating an alias method chain on find in AssociationCollection
|
5
|
+
* Added modifiers: upper, lower, trim, ltrim, rtrim
|
6
|
+
* Added not_nil and not_blank conditions
|
7
|
+
* Modified conditions so that table name is a variable, this allows table name to be switched on the fly.
|
8
|
+
* Modified auto joins to return symbols instead of SQL. This allows AR to properly merge the joins and ultimately result in proper SQL when performing multiple complex scopes.
|
9
|
+
* Fixed conflicts between includes and joins, duplicate joins are not added. Includes are prioritized. This also makes ActiveRecord much more flexible. Now you can cherry pick included associations. And not have to worry about conflicting with joins.
|
10
|
+
* Modified ActiveRecord's default behavior to use inner joins with the :joins option. Inner joins impose limitations. When providing this as a "convenience", inner joins do not make sense. The don't allow OR conditions to be across associations, nor does it properly order when an ordering by an association attribute when that association is optional.
|
11
|
+
|
1
12
|
== 1.3.5 released 2008-10-08
|
2
13
|
|
3
14
|
* Since joins are now strings, AR doesn't know how to merge them properly. So searchgasm now checks which joins to skip over to avoid conflicts.
|
data/Manifest
CHANGED
@@ -22,10 +22,12 @@ lib/searchgasm/condition/less_than_or_equal_to.rb
|
|
22
22
|
lib/searchgasm/condition/like.rb
|
23
23
|
lib/searchgasm/condition/nil.rb
|
24
24
|
lib/searchgasm/condition/not_begin_with.rb
|
25
|
+
lib/searchgasm/condition/not_blank.rb
|
25
26
|
lib/searchgasm/condition/not_end_with.rb
|
26
27
|
lib/searchgasm/condition/not_equal.rb
|
27
28
|
lib/searchgasm/condition/not_have_keywords.rb
|
28
29
|
lib/searchgasm/condition/not_like.rb
|
30
|
+
lib/searchgasm/condition/not_nil.rb
|
29
31
|
lib/searchgasm/condition/sibling_of.rb
|
30
32
|
lib/searchgasm/condition/tree.rb
|
31
33
|
lib/searchgasm/conditions/base.rb
|
@@ -60,6 +62,8 @@ lib/searchgasm/modifiers/hour.rb
|
|
60
62
|
lib/searchgasm/modifiers/log.rb
|
61
63
|
lib/searchgasm/modifiers/log10.rb
|
62
64
|
lib/searchgasm/modifiers/log2.rb
|
65
|
+
lib/searchgasm/modifiers/lower.rb
|
66
|
+
lib/searchgasm/modifiers/ltrim.rb
|
63
67
|
lib/searchgasm/modifiers/md5.rb
|
64
68
|
lib/searchgasm/modifiers/microseconds.rb
|
65
69
|
lib/searchgasm/modifiers/milliseconds.rb
|
@@ -68,11 +72,14 @@ lib/searchgasm/modifiers/month.rb
|
|
68
72
|
lib/searchgasm/modifiers/octal.rb
|
69
73
|
lib/searchgasm/modifiers/radians.rb
|
70
74
|
lib/searchgasm/modifiers/round.rb
|
75
|
+
lib/searchgasm/modifiers/rtrim.rb
|
71
76
|
lib/searchgasm/modifiers/second.rb
|
72
77
|
lib/searchgasm/modifiers/sign.rb
|
73
78
|
lib/searchgasm/modifiers/sin.rb
|
74
79
|
lib/searchgasm/modifiers/square_root.rb
|
75
80
|
lib/searchgasm/modifiers/tan.rb
|
81
|
+
lib/searchgasm/modifiers/trim.rb
|
82
|
+
lib/searchgasm/modifiers/upper.rb
|
76
83
|
lib/searchgasm/modifiers/week.rb
|
77
84
|
lib/searchgasm/modifiers/year.rb
|
78
85
|
lib/searchgasm/search/base.rb
|
@@ -90,12 +97,11 @@ MIT-LICENSE
|
|
90
97
|
Rakefile
|
91
98
|
README.rdoc
|
92
99
|
test/fixtures/accounts.yml
|
100
|
+
test/fixtures/cats.yml
|
101
|
+
test/fixtures/dogs.yml
|
93
102
|
test/fixtures/orders.yml
|
94
103
|
test/fixtures/user_groups.yml
|
95
104
|
test/fixtures/users.yml
|
96
|
-
test/libs/acts_as_tree.rb
|
97
|
-
test/libs/ordered_hash.rb
|
98
|
-
test/libs/rexml_fix.rb
|
99
105
|
test/test_active_record_associations.rb
|
100
106
|
test/test_active_record_base.rb
|
101
107
|
test/test_condition_base.rb
|
@@ -109,4 +115,7 @@ test/test_search_conditions.rb
|
|
109
115
|
test/test_search_ordering.rb
|
110
116
|
test/test_search_pagination.rb
|
111
117
|
test/test_search_protection.rb
|
118
|
+
test_libs/acts_as_tree.rb
|
119
|
+
test_libs/ordered_hash.rb
|
120
|
+
test_libs/rexml_fix.rb
|
112
121
|
TODO.rdoc
|
data/README.rdoc
CHANGED
@@ -305,6 +305,11 @@ Here are all of the available modifiers:
|
|
305
305
|
|
306
306
|
:md5 Converts to a MD5
|
307
307
|
:char_length :length The length of the string (integer)
|
308
|
+
:lower :downcase, :lcase Converts the string to all lower case characters
|
309
|
+
:ltrin :lstrip Strips off spaces from the beginning of the string
|
310
|
+
:trim :strip Strips off spaces from the beginning and end of the string
|
311
|
+
:rtrim :rstrip Strips off spaces from the end of the string
|
312
|
+
:upper :upcase, :ucase Converts the string to all upper case character
|
308
313
|
|
309
314
|
:absolute :abs The absolute value (-1 => 1)
|
310
315
|
:acos The arc cosine
|
@@ -344,6 +349,12 @@ Here's the cool part. Chaining modifiers:
|
|
344
349
|
|
345
350
|
As long as the modifier chain makes sense the possibilities are endless.
|
346
351
|
|
352
|
+
=== Modifiers are not indexed
|
353
|
+
|
354
|
+
Depending on your database you can create complex indexes. But chances are you probably didn't or don't plan to. So keep in mind that once you use a modifier it will not be using an index, meaning the query will be slower. One of the ways to get the best of both worlds is to cache virtual attributes in the database. Checkout my tutorial:
|
355
|
+
|
356
|
+
http://www.binarylogic.com/2008/10/5/tutorial-caching-virtual-attributes-in-the-database
|
357
|
+
|
347
358
|
== Roll your own conditions & modifiers
|
348
359
|
|
349
360
|
For more information on this please see Searchgasm::Conditions::Base
|
data/TODO.rdoc
CHANGED
@@ -1,3 +1,6 @@
|
|
1
1
|
= To Do
|
2
2
|
|
3
|
-
1. Perform "more efficient" checks: year_of_created_at = 2008 and month_of_created_at = 8. Should result in a "BETWEEN" statement utilizing the column indexes. Thanks Georg for letting me know about this.
|
3
|
+
1. Perform "more efficient" checks: year_of_created_at = 2008 and month_of_created_at = 8. Should result in a "BETWEEN" statement utilizing the column indexes. Thanks Georg for letting me know about this.
|
4
|
+
2. Solve conflicts between scope joins and joins in the search (for old versions of AR). Also solve conflicts between joins and includes.
|
5
|
+
3. Add configuration to change the "english" words
|
6
|
+
4. Re-add the distinct option
|
@@ -13,7 +13,7 @@ module Searchgasm
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
module
|
16
|
+
module HasManyAssociation
|
17
17
|
def count_with_searchgasm(*args)
|
18
18
|
options = args.extract_options!
|
19
19
|
args << filter_options_with_searchgasm(options)
|
@@ -24,18 +24,29 @@ module Searchgasm
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
alias_method_chain :find, :searchgasm
|
33
|
-
end
|
34
|
-
|
35
|
-
class HasManyAssociation
|
36
|
-
include Searchgasm::ActiveRecord::Associations::Shared
|
37
|
-
|
38
|
-
alias_method_chain :count, :searchgasm
|
39
|
-
end
|
27
|
+
ActiveRecord::Associations::AssociationCollection.class_eval do
|
28
|
+
if respond_to?(:find)
|
29
|
+
include Searchgasm::ActiveRecord::Associations::AssociationCollection
|
30
|
+
alias_method_chain :find, :searchgasm
|
40
31
|
end
|
32
|
+
end
|
33
|
+
|
34
|
+
ActiveRecord::Associations::HasManyAssociation.class_eval do
|
35
|
+
include Searchgasm::ActiveRecord::Associations::HasManyAssociation
|
36
|
+
alias_method_chain :count, :searchgasm
|
37
|
+
|
38
|
+
# Older versions of AR have find in here, not in AssociationCollection
|
39
|
+
include Searchgasm::ActiveRecord::Associations::AssociationCollection
|
40
|
+
alias_method_chain :find, :searchgasm
|
41
|
+
end
|
42
|
+
|
43
|
+
ActiveRecord::Associations::ClassMethods::InnerJoinDependency::InnerJoinAssociation.class_eval do
|
44
|
+
private
|
45
|
+
# Inner joins impose limitations on queries. They can be quicker but you can't do OR conditions when conditions
|
46
|
+
# overlap from the base model to any of its associations. Also, inner joins won't allow you to order by an association
|
47
|
+
# attribute. What if the association is optional? All of those records are ommitted. It just doesn't make sense to default
|
48
|
+
# to inner joins when providing this as a "convenience" when searching. So let's change it.
|
49
|
+
def join_type
|
50
|
+
"LEFT OUTER JOIN"
|
51
|
+
end
|
41
52
|
end
|
@@ -165,6 +165,55 @@ module ActiveRecord #:nodoc: all
|
|
165
165
|
def valid_calculations_options
|
166
166
|
Calculations::CALCULATIONS_OPTIONS
|
167
167
|
end
|
168
|
+
|
169
|
+
private
|
170
|
+
# This is copied over from 2 different versions of ActiveRecord. I have to do this in order to preserve the "auto joins"
|
171
|
+
# as symbols. Keeping them as symbols allows ActiveRecord to merge them properly. The problem is when they conflict with includes.
|
172
|
+
# Includes add joins also, and they add them before joins do. So if they already added them skip them. Now you can do queries like:
|
173
|
+
#
|
174
|
+
# User.all(:joins => {:orders => :line_items}, :include => :orders)
|
175
|
+
#
|
176
|
+
# Where as before, the only way to get the above query to work would be to include line_items also, which is not neccessarily what you want.
|
177
|
+
def add_joins!(sql, options_or_joins, scope = :auto) # :nodoc:
|
178
|
+
code_type = array_of_strings?([""]) && :array_of_strings rescue nil
|
179
|
+
code_type ||= merge_joins("", "") && :merge_joins rescue nil
|
180
|
+
|
181
|
+
case code_type
|
182
|
+
when :array_of_strings, :merge_joins
|
183
|
+
joins = options_or_joins
|
184
|
+
scope = scope(:find) if :auto == scope
|
185
|
+
merged_joins = scope && scope[:joins] && joins ? merge_joins(scope[:joins], joins) : (joins || scope && scope[:joins])
|
186
|
+
case merged_joins
|
187
|
+
when Symbol, Hash, Array
|
188
|
+
if code_type == :array_of_strings && array_of_strings?(merged_joins)
|
189
|
+
merged_joins.each { |merged_join| sql << " #{merged_join} " unless sql.include?(merged_join) }
|
190
|
+
else
|
191
|
+
join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, merged_joins, nil)
|
192
|
+
join_dependency.join_associations.each do |assoc|
|
193
|
+
join_sql = assoc.association_join
|
194
|
+
sql << " #{join_sql} " unless sql.include?(join_sql)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
when String
|
198
|
+
sql << " #{merged_joins} " if merged_joins && !sql.include?(merged_joins)
|
199
|
+
end
|
200
|
+
else
|
201
|
+
options = options_or_joins
|
202
|
+
scope = scope(:find) if :auto == scope
|
203
|
+
[(scope && scope[:joins]), options[:joins]].each do |join|
|
204
|
+
case join
|
205
|
+
when Symbol, Hash, Array
|
206
|
+
join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, join, nil)
|
207
|
+
join_dependency.join_associations.each do |assoc|
|
208
|
+
join_sql = assoc.association_join
|
209
|
+
sql << " #{join_sql} " unless sql.include?(join_sql)
|
210
|
+
end
|
211
|
+
else
|
212
|
+
sql << " #{join} " if join && !sql.include?(join)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
168
217
|
end
|
169
218
|
end
|
170
219
|
end
|
@@ -52,10 +52,30 @@ module Searchgasm
|
|
52
52
|
"CHAR_LENGTH(#{column_name})"
|
53
53
|
end
|
54
54
|
|
55
|
+
def lower_sql(column_name)
|
56
|
+
"LOWER(#{column_name})"
|
57
|
+
end
|
58
|
+
|
59
|
+
def ltrim_sql(column_name)
|
60
|
+
"LTRIM(#{column_name})"
|
61
|
+
end
|
62
|
+
|
55
63
|
def md5_sql(column_name)
|
56
64
|
"MD5(#{column_name})"
|
57
65
|
end
|
58
66
|
|
67
|
+
def rtrim_sql(column_name)
|
68
|
+
"RTRIM(#{column_name})"
|
69
|
+
end
|
70
|
+
|
71
|
+
def trim_sql(column_name)
|
72
|
+
"TRIM(#{column_name})"
|
73
|
+
end
|
74
|
+
|
75
|
+
def upper_sql(column_name)
|
76
|
+
"UPPER(#{column_name})"
|
77
|
+
end
|
78
|
+
|
59
79
|
# Number functions
|
60
80
|
def absolute_sql(column_name)
|
61
81
|
"ABS(#{column_name})"
|
@@ -52,10 +52,30 @@ module Searchgasm
|
|
52
52
|
"length(#{column_name})"
|
53
53
|
end
|
54
54
|
|
55
|
+
def lower_sql(column_name)
|
56
|
+
"lower(#{column_name})"
|
57
|
+
end
|
58
|
+
|
59
|
+
def ltrim_sql(column_name)
|
60
|
+
"ltrim(#{column_name})"
|
61
|
+
end
|
62
|
+
|
55
63
|
def md5_sql(column_name)
|
56
64
|
"md5(#{column_name})"
|
57
65
|
end
|
58
66
|
|
67
|
+
def rtrim_sql(column_name)
|
68
|
+
"rtrim(#{column_name})"
|
69
|
+
end
|
70
|
+
|
71
|
+
def trim_sql(column_name)
|
72
|
+
"trim(#{column_name})"
|
73
|
+
end
|
74
|
+
|
75
|
+
def upper_sql(column_name)
|
76
|
+
"upper(#{column_name})"
|
77
|
+
end
|
78
|
+
|
59
79
|
# Number functions
|
60
80
|
def absolute_sql(column_name)
|
61
81
|
"abs(#{column_name})"
|
@@ -46,6 +46,27 @@ module Searchgasm
|
|
46
46
|
def year_sql(column_name)
|
47
47
|
"strftime('%Y', #{column_name})"
|
48
48
|
end
|
49
|
+
|
50
|
+
# String functions
|
51
|
+
def lower_sql(column_name)
|
52
|
+
"lower(#{column_name})"
|
53
|
+
end
|
54
|
+
|
55
|
+
def ltrim_sql(column_name)
|
56
|
+
"ltrim(#{column_name})"
|
57
|
+
end
|
58
|
+
|
59
|
+
def rtrim_sql(column_name)
|
60
|
+
"rtrim(#{column_name})"
|
61
|
+
end
|
62
|
+
|
63
|
+
def trim_sql(column_name)
|
64
|
+
"trim(#{column_name})"
|
65
|
+
end
|
66
|
+
|
67
|
+
def upper_sql(column_name)
|
68
|
+
"upper(#{column_name})"
|
69
|
+
end
|
49
70
|
end
|
50
71
|
end
|
51
72
|
end
|
@@ -7,7 +7,7 @@ module Searchgasm
|
|
7
7
|
class Base
|
8
8
|
include Shared::Utilities
|
9
9
|
|
10
|
-
attr_accessor :column, :column_for_type_cast, :column_sql, :klass
|
10
|
+
attr_accessor :column, :column_for_type_cast, :column_sql, :column_sql_format, :klass, :table_name
|
11
11
|
class_inheritable_accessor :handle_array_value, :ignore_meaningless_value, :value_type
|
12
12
|
self.ignore_meaningless_value = true
|
13
13
|
|
@@ -16,7 +16,7 @@ module Searchgasm
|
|
16
16
|
def condition_type_name
|
17
17
|
name.split("::").last.underscore
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def handle_array_value?
|
21
21
|
handle_array_value == true
|
22
22
|
end
|
@@ -39,16 +39,29 @@ module Searchgasm
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
def initialize(klass,
|
42
|
+
def initialize(klass, options = {})
|
43
43
|
self.klass = klass
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
44
|
+
self.table_name = options[:table_name] || klass.table_name
|
45
|
+
|
46
|
+
if options[:column]
|
47
|
+
self.column = options[:column].class < ::ActiveRecord::ConnectionAdapters::Column ? options[:column] : klass.columns_hash[options[:column].to_s]
|
48
|
+
|
49
|
+
if options[:column_for_type_cast]
|
50
|
+
self.column_for_type_cast = options[:column_for_type_cast]
|
51
|
+
else
|
52
|
+
type = (!self.class.value_type.blank? && self.class.value_type.to_s) || (!options[:column_type].blank? && options[:column_type].to_s) || column.sql_type
|
53
|
+
self.column_for_type_cast = column.class.new(column.name, column.default.to_s, type, column.null)
|
54
|
+
end
|
55
|
+
|
56
|
+
self.column_sql_format = options[:column_sql_format] || "{table}.{column}"
|
50
57
|
end
|
51
58
|
end
|
59
|
+
|
60
|
+
# Substitutes string vars with table and column name. Allows us to switch the column and table on the fly and have the condition update appropriately.
|
61
|
+
# The table name could be variable depending on the condition. Take STI and more than one child model is used in the condition, the first gets the parent table name, the rest get aliases.
|
62
|
+
def column_sql
|
63
|
+
column_sql_format.gsub("{table}", quoted_table_name).gsub("{column}", quoted_column_name)
|
64
|
+
end
|
52
65
|
|
53
66
|
# Allows nils to be meaninful values
|
54
67
|
def explicitly_set_value=(value)
|
@@ -60,6 +73,10 @@ module Searchgasm
|
|
60
73
|
@explicitly_set_value == true
|
61
74
|
end
|
62
75
|
|
76
|
+
def options
|
77
|
+
{:table_name => table_name, :column => column, :column_for_type_cast => column_for_type_cast, :column_sql_format => column_sql_format}
|
78
|
+
end
|
79
|
+
|
63
80
|
# You should refrain from overwriting this method, it performs various tasks before callign your to_conditions method, allowing you to keep to_conditions simple.
|
64
81
|
def sanitize(alt_value = nil) # :nodoc:
|
65
82
|
return if value_is_meaningless?
|
@@ -107,12 +124,16 @@ module Searchgasm
|
|
107
124
|
klass.connection.quote_column_name(column_name)
|
108
125
|
end
|
109
126
|
|
127
|
+
def quoted_column_name
|
128
|
+
quote_column_name(column.name)
|
129
|
+
end
|
130
|
+
|
110
131
|
def quote_table_name(table_name)
|
111
132
|
klass.connection.quote_table_name(table_name)
|
112
133
|
end
|
113
134
|
|
114
135
|
def quoted_table_name
|
115
|
-
quote_table_name(
|
136
|
+
quote_table_name(table_name)
|
116
137
|
end
|
117
138
|
|
118
139
|
def type_cast_value(v)
|
@@ -2,7 +2,7 @@ module Searchgasm
|
|
2
2
|
module Condition
|
3
3
|
class InclusiveDescendantOf < Tree
|
4
4
|
def to_conditions(value)
|
5
|
-
condition = DescendantOf.new(klass,
|
5
|
+
condition = DescendantOf.new(klass, options)
|
6
6
|
condition.value = value
|
7
7
|
merge_conditions(["#{quoted_table_name}.#{quote_column_name(klass.primary_key)} = ?", (value.is_a?(klass) ? value.send(klass.primary_key) : value)], condition.sanitize, :any => true)
|
8
8
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Searchgasm
|
2
|
+
module Condition
|
3
|
+
class NotBlank < Base
|
4
|
+
class << self
|
5
|
+
def condition_names_for_column
|
6
|
+
super + ["is_not_blank"]
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_conditions(value)
|
11
|
+
blank = Blank.new(klass, options)
|
12
|
+
blank.value = !value
|
13
|
+
blank.to_conditions
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Searchgasm
|
2
|
+
module Condition
|
3
|
+
class NotNil < Base
|
4
|
+
class << self
|
5
|
+
def condition_names_for_column
|
6
|
+
super + ["is_not_nil", "is_not_null", "not_null"]
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_conditions(value)
|
11
|
+
is_nil = Nil.new(klass, options)
|
12
|
+
is_nil.value = !value
|
13
|
+
is_nil.to_conditions
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -5,7 +5,7 @@ module Searchgasm
|
|
5
5
|
parent_association = klass.reflect_on_association(:parent)
|
6
6
|
foreign_key_name = (parent_association && parent_association.options[:foreign_key]) || "parent_id"
|
7
7
|
parent_id = (value.is_a?(klass) ? value : klass.find(value)).send(foreign_key_name)
|
8
|
-
condition = ChildOf.new(klass,
|
8
|
+
condition = ChildOf.new(klass, options)
|
9
9
|
condition.value = parent_id
|
10
10
|
merge_conditions(["#{quoted_table_name}.#{quote_column_name(klass.primary_key)} != ?", (value.is_a?(klass) ? value.send(klass.primary_key) : value)], condition.sanitize)
|
11
11
|
end
|
@@ -179,7 +179,7 @@ module Searchgasm
|
|
179
179
|
associations.each do |name, association|
|
180
180
|
next if association.conditions.blank?
|
181
181
|
association_joins = association.auto_joins
|
182
|
-
j << (association_joins.blank? ?
|
182
|
+
j << (association_joins.blank? ? name : {name => association_joins})
|
183
183
|
end
|
184
184
|
j.blank? ? nil : (j.size == 1 ? j.first : j)
|
185
185
|
end
|
@@ -233,7 +233,7 @@ module Searchgasm
|
|
233
233
|
if object.class < Searchgasm::Conditions::Base
|
234
234
|
relationship_conditions = object.conditions
|
235
235
|
next if relationship_conditions.blank?
|
236
|
-
conditions_hash[
|
236
|
+
conditions_hash[name] = relationship_conditions
|
237
237
|
else
|
238
238
|
next if object.value_is_meaningless?
|
239
239
|
conditions_hash[name] = object.value
|
@@ -367,14 +367,14 @@ module Searchgasm
|
|
367
367
|
column_type = modifier_klasses.first.return_type
|
368
368
|
|
369
369
|
# Build the column sql
|
370
|
-
column_sql = "
|
370
|
+
column_sql = "{table}.{column}"
|
371
371
|
modifier_klasses.each do |modifier_klass|
|
372
372
|
next unless klass.connection.respond_to?(modifier_klass.adapter_method_name)
|
373
373
|
column_sql = klass.connection.send(modifier_klass.adapter_method_name, column_sql)
|
374
374
|
end
|
375
375
|
end
|
376
376
|
|
377
|
-
add_condition!(condition_klass, method_name, column_detail[:column], column_type, column_sql)
|
377
|
+
add_condition!(condition_klass, method_name, :column => column_detail[:column], :column_type => column_type, :column_sql_format => column_sql)
|
378
378
|
|
379
379
|
([column_detail[:column].name] + column_detail[:aliases]).each do |column_name|
|
380
380
|
condition_klass.condition_names_for_column.each do |condition_name|
|
@@ -393,13 +393,15 @@ module Searchgasm
|
|
393
393
|
false
|
394
394
|
end
|
395
395
|
|
396
|
-
def add_condition!(condition, name,
|
396
|
+
def add_condition!(condition, name, options = {})
|
397
397
|
self.class.condition_names << name
|
398
|
+
options[:column] = options[:column].name if options[:column].class < ::ActiveRecord::ConnectionAdapters::Column
|
398
399
|
|
399
400
|
self.class.class_eval <<-"end_eval", __FILE__, __LINE__
|
400
401
|
def #{name}_object
|
401
402
|
if objects[:#{name}].nil?
|
402
|
-
|
403
|
+
options = {}
|
404
|
+
objects[:#{name}] = #{condition.name}.new(klass, #{options.inspect})
|
403
405
|
end
|
404
406
|
objects[:#{name}]
|
405
407
|
end
|
@@ -465,7 +467,7 @@ module Searchgasm
|
|
465
467
|
end
|
466
468
|
|
467
469
|
def reset_objects!
|
468
|
-
objects.each { |name, object|
|
470
|
+
objects.each { |name, object| eval("@#{name} = nil") }
|
469
471
|
objects.clear
|
470
472
|
end
|
471
473
|
|
@@ -105,7 +105,7 @@ module Searchgasm
|
|
105
105
|
# === Options
|
106
106
|
# * <tt>:params_scope</tt> -- default: :search, this is the scope in which your search params will be preserved (params[:search]). If you don't want a scope and want your options to be at base leve in params such as params[:page], params[:per_page], etc, then set this to nil.
|
107
107
|
# * <tt>:search_obj</tt> -- default: @#{params_scope}, this is your search object, everything revolves around this. It will try to infer the name from your params_scope. If your params_scope is :search it will try to get @search, etc. If it can not be inferred by this, you need to pass the object itself.
|
108
|
-
def searchgasm_state(options)
|
108
|
+
def searchgasm_state(options = {})
|
109
109
|
return "" if @added_searchgasm_state
|
110
110
|
add_searchgasm_defaults!(options)
|
111
111
|
html = ""
|