searchlogic 2.4.12 → 2.4.13
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION.yml +1 -1
- data/lib/searchlogic/core_ext/object.rb +4 -2
- data/lib/searchlogic/core_ext/proc.rb +7 -1
- data/lib/searchlogic/named_scopes/association_conditions.rb +1 -1
- data/lib/searchlogic/named_scopes/conditions.rb +18 -17
- data/lib/searchlogic/named_scopes/or_conditions.rb +1 -1
- data/lib/searchlogic/search.rb +21 -6
- data/searchlogic.gemspec +2 -2
- data/spec/core_ext/object_spec.rb +4 -2
- data/spec/core_ext/proc_spec.rb +2 -3
- data/spec/named_scopes/conditions_spec.rb +3 -3
- data/spec/search_spec.rb +6 -0
- data/spec/spec_helper.rb +3 -0
- metadata +3 -3
data/VERSION.yml
CHANGED
@@ -31,9 +31,11 @@ module Searchlogic
|
|
31
31
|
# If you want something else, you need to specify it as I did in the above example. Comments are appreciated
|
32
32
|
# on this, if you know of a better solution please let me know. But this is the best I could come up with,
|
33
33
|
# without being intrusive and altering default behavior.
|
34
|
-
def searchlogic_lambda(type = :string, &block)
|
34
|
+
def searchlogic_lambda(type = :string, options = {}, &block)
|
35
35
|
proc = lambda(&block)
|
36
|
-
proc.
|
36
|
+
proc.searchlogic_options ||= {}
|
37
|
+
proc.searchlogic_options[:type] = type
|
38
|
+
proc.searchlogic_options.merge!(options)
|
37
39
|
proc
|
38
40
|
end
|
39
41
|
end
|
@@ -3,7 +3,13 @@ module Searchlogic
|
|
3
3
|
module Proc # :nodoc:
|
4
4
|
def self.included(klass)
|
5
5
|
klass.class_eval do
|
6
|
-
attr_accessor :
|
6
|
+
attr_accessor :searchlogic_options
|
7
|
+
|
8
|
+
def searchlogic_options
|
9
|
+
@searchlogic_options ||= {}
|
10
|
+
@searchlogic_options[:type] ||= :string
|
11
|
+
@searchlogic_options
|
12
|
+
end
|
7
13
|
end
|
8
14
|
end
|
9
15
|
end
|
@@ -71,7 +71,7 @@ module Searchlogic
|
|
71
71
|
options
|
72
72
|
else
|
73
73
|
proc_args = arity_args(arity)
|
74
|
-
arg_type = (scope_options.respond_to?(:
|
74
|
+
arg_type = (scope_options.respond_to?(:searchlogic_options) && scope_options.searchlogic_options[:type]) || :string
|
75
75
|
|
76
76
|
eval <<-"end_eval"
|
77
77
|
searchlogic_lambda(:#{arg_type}) { |#{proc_args.join(",")}|
|
@@ -108,33 +108,34 @@ module Searchlogic
|
|
108
108
|
|
109
109
|
def create_primary_condition(column, condition)
|
110
110
|
column_type = columns_hash[column.to_s].type
|
111
|
+
skip_conversion = skip_time_zone_conversion_for_attributes.include?(columns_hash[column.to_s].name.to_sym)
|
111
112
|
match_keyword = ::ActiveRecord::Base.connection.adapter_name == "PostgreSQL" ? "ILIKE" : "LIKE"
|
112
113
|
|
113
114
|
scope_options = case condition.to_s
|
114
115
|
when /^equals/
|
115
|
-
scope_options(condition, column_type, lambda { |a| attribute_condition("#{table_name}.#{column}", a) })
|
116
|
+
scope_options(condition, column_type, lambda { |a| attribute_condition("#{table_name}.#{column}", a) }, :skip_conversion => skip_conversion)
|
116
117
|
when /^does_not_equal/
|
117
|
-
scope_options(condition, column_type, "#{table_name}.#{column} != ?")
|
118
|
+
scope_options(condition, column_type, "#{table_name}.#{column} != ?", :skip_conversion => skip_conversion)
|
118
119
|
when /^less_than_or_equal_to/
|
119
|
-
scope_options(condition, column_type, "#{table_name}.#{column} <= ?")
|
120
|
+
scope_options(condition, column_type, "#{table_name}.#{column} <= ?", :skip_conversion => skip_conversion)
|
120
121
|
when /^less_than/
|
121
|
-
scope_options(condition, column_type, "#{table_name}.#{column} < ?")
|
122
|
+
scope_options(condition, column_type, "#{table_name}.#{column} < ?", :skip_conversion => skip_conversion)
|
122
123
|
when /^greater_than_or_equal_to/
|
123
|
-
scope_options(condition, column_type, "#{table_name}.#{column} >= ?")
|
124
|
+
scope_options(condition, column_type, "#{table_name}.#{column} >= ?", :skip_conversion => skip_conversion)
|
124
125
|
when /^greater_than/
|
125
|
-
scope_options(condition, column_type, "#{table_name}.#{column} > ?")
|
126
|
+
scope_options(condition, column_type, "#{table_name}.#{column} > ?", :skip_conversion => skip_conversion)
|
126
127
|
when /^like/
|
127
|
-
scope_options(condition, column_type, "#{table_name}.#{column} #{match_keyword} ?", :like)
|
128
|
+
scope_options(condition, column_type, "#{table_name}.#{column} #{match_keyword} ?", :skip_conversion => skip_conversion, :value_modifier => :like)
|
128
129
|
when /^not_like/
|
129
|
-
scope_options(condition, column_type, "#{table_name}.#{column} NOT #{match_keyword} ?", :like)
|
130
|
+
scope_options(condition, column_type, "#{table_name}.#{column} NOT #{match_keyword} ?", :skip_conversion => skip_conversion, :value_modifier => :like)
|
130
131
|
when /^begins_with/
|
131
|
-
scope_options(condition, column_type, "#{table_name}.#{column} #{match_keyword} ?", :begins_with)
|
132
|
+
scope_options(condition, column_type, "#{table_name}.#{column} #{match_keyword} ?", :skip_conversion => skip_conversion, :value_modifier => :begins_with)
|
132
133
|
when /^not_begin_with/
|
133
|
-
scope_options(condition, column_type, "#{table_name}.#{column} NOT #{match_keyword} ?", :begins_with)
|
134
|
+
scope_options(condition, column_type, "#{table_name}.#{column} NOT #{match_keyword} ?", :skip_conversion => skip_conversion, :value_modifier => :begins_with)
|
134
135
|
when /^ends_with/
|
135
|
-
scope_options(condition, column_type, "#{table_name}.#{column} #{match_keyword} ?", :ends_with)
|
136
|
+
scope_options(condition, column_type, "#{table_name}.#{column} #{match_keyword} ?", :skip_conversion => skip_conversion, :value_modifier => :ends_with)
|
136
137
|
when /^not_end_with/
|
137
|
-
scope_options(condition, column_type, "#{table_name}.#{column} NOT #{match_keyword} ?", :ends_with)
|
138
|
+
scope_options(condition, column_type, "#{table_name}.#{column} NOT #{match_keyword} ?", :skip_conversion => skip_conversion, :value_modifier => :ends_with)
|
138
139
|
when "null"
|
139
140
|
{:conditions => "#{table_name}.#{column} IS NULL"}
|
140
141
|
when "not_null"
|
@@ -153,13 +154,13 @@ module Searchlogic
|
|
153
154
|
# This method helps cut down on defining scope options for conditions that allow *_any or *_all conditions.
|
154
155
|
# Kepp in mind that the lambdas get cached in a method, so you want to keep the contents of the lambdas as
|
155
156
|
# fast as possible, which is why I didn't do the case statement inside of the lambda.
|
156
|
-
def scope_options(condition, column_type, sql,
|
157
|
+
def scope_options(condition, column_type, sql, options = {})
|
157
158
|
case condition.to_s
|
158
159
|
when /_(any|all)$/
|
159
|
-
searchlogic_lambda(column_type) { |*values|
|
160
|
+
searchlogic_lambda(column_type, :skip_conversion => options[:skip_conversion]) { |*values|
|
160
161
|
return {} if values.empty?
|
161
162
|
values.flatten!
|
162
|
-
values.collect! { |value| value_with_modifier(value, value_modifier) }
|
163
|
+
values.collect! { |value| value_with_modifier(value, options[:value_modifier]) }
|
163
164
|
|
164
165
|
join = $1 == "any" ? " OR " : " AND "
|
165
166
|
scope_sql = values.collect { |value| sql.is_a?(Proc) ? sql.call(value) : sql }.join(join)
|
@@ -167,8 +168,8 @@ module Searchlogic
|
|
167
168
|
{:conditions => [scope_sql, *expand_range_bind_variables(values)]}
|
168
169
|
}
|
169
170
|
else
|
170
|
-
searchlogic_lambda(column_type) { |*values|
|
171
|
-
values.collect! { |value| value_with_modifier(value, value_modifier) }
|
171
|
+
searchlogic_lambda(column_type, :skip_conversion => options[:skip_conversion]) { |*values|
|
172
|
+
values.collect! { |value| value_with_modifier(value, options[:value_modifier]) }
|
172
173
|
|
173
174
|
scope_sql = sql.is_a?(Proc) ? sql.call(*values) : sql
|
174
175
|
|
@@ -121,7 +121,7 @@ module Searchlogic
|
|
121
121
|
scopes_options = scopes.collect { |scope, *args| send(scope, *args).proxy_options }
|
122
122
|
# We're using first scope to determine column's type
|
123
123
|
scope = named_scope_options(scopes.first)
|
124
|
-
column_type = scope.respond_to?(:
|
124
|
+
column_type = scope.respond_to?(:searchlogic_options) ? scope.searchlogic_options[:type] : :string
|
125
125
|
named_scope scopes.join("_or_"), searchlogic_lambda(column_type) { |*args|
|
126
126
|
merge_scopes_with_or(scopes.collect { |scope| clone.send(scope, *args) })
|
127
127
|
}
|
data/lib/searchlogic/search.rb
CHANGED
@@ -90,7 +90,14 @@ module Searchlogic
|
|
90
90
|
if setter?(name)
|
91
91
|
if scope?(scope_name)
|
92
92
|
if args.size == 1
|
93
|
-
write_condition(
|
93
|
+
write_condition(
|
94
|
+
condition_name,
|
95
|
+
type_cast(
|
96
|
+
args.first,
|
97
|
+
cast_type(scope_name),
|
98
|
+
scope_options(scope_name).respond_to?(:searchlogic_options) ? scope_options(scope_name).searchlogic_options : {}
|
99
|
+
)
|
100
|
+
)
|
94
101
|
else
|
95
102
|
write_condition(condition_name, args)
|
96
103
|
end
|
@@ -169,18 +176,22 @@ module Searchlogic
|
|
169
176
|
klass.scopes.key?(scope_name) || klass.condition?(scope_name)
|
170
177
|
end
|
171
178
|
|
172
|
-
def
|
179
|
+
def scope_options(name)
|
173
180
|
klass.send(name, nil) if !klass.respond_to?(name) # We need to set up the named scope if it doesn't exist, so we can get a value for named_scope_options
|
174
|
-
|
181
|
+
klass.named_scope_options(name)
|
182
|
+
end
|
183
|
+
|
184
|
+
def cast_type(name)
|
185
|
+
named_scope_options = scope_options(name)
|
175
186
|
arity = klass.named_scope_arity(name)
|
176
187
|
if !arity || arity == 0
|
177
188
|
:boolean
|
178
189
|
else
|
179
|
-
named_scope_options.respond_to?(:
|
190
|
+
named_scope_options.respond_to?(:searchlogic_options) ? named_scope_options.searchlogic_options[:type] : :string
|
180
191
|
end
|
181
192
|
end
|
182
193
|
|
183
|
-
def type_cast(value, type)
|
194
|
+
def type_cast(value, type, options = {})
|
184
195
|
case value
|
185
196
|
when Array
|
186
197
|
value.collect { |v| type_cast(v, type) }
|
@@ -195,7 +206,11 @@ module Searchlogic
|
|
195
206
|
|
196
207
|
if Time.zone && casted_value.is_a?(Time)
|
197
208
|
if value.is_a?(String)
|
198
|
-
|
209
|
+
if options[:skip_conversion]
|
210
|
+
casted_value.utc
|
211
|
+
else
|
212
|
+
(casted_value + (Time.zone.utc_offset * -1)).in_time_zone
|
213
|
+
end
|
199
214
|
else
|
200
215
|
casted_value.in_time_zone
|
201
216
|
end
|
data/searchlogic.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{searchlogic}
|
8
|
-
s.version = "2.4.
|
8
|
+
s.version = "2.4.13"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ben Johnson of Binary Logic"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-04-04}
|
13
13
|
s.description = %q{Searchlogic makes using ActiveRecord named scopes easier and less repetitive.}
|
14
14
|
s.email = %q{bjohnson@binarylogic.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -1,7 +1,9 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
2
|
|
3
3
|
describe "Object" do
|
4
|
-
it "should accept and pass the argument to the
|
5
|
-
searchlogic_lambda(:integer) {}
|
4
|
+
it "should accept and pass the argument to the searchlogic_options" do
|
5
|
+
proc = searchlogic_lambda(:integer, :test => :value) {}
|
6
|
+
proc.searchlogic_options[:type].should == :integer
|
7
|
+
proc.searchlogic_options[:test].should == :value
|
6
8
|
end
|
7
9
|
end
|
data/spec/core_ext/proc_spec.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
2
|
|
3
3
|
describe "Proc" do
|
4
|
-
it "should have a
|
4
|
+
it "should have a searchlogic_options accessor" do
|
5
5
|
p = Proc.new {}
|
6
|
-
p.
|
7
|
-
p.searchlogic_arg_type.should == :integer
|
6
|
+
p.searchlogic_options[:type] = :integer
|
8
7
|
end
|
9
8
|
end
|
@@ -290,17 +290,17 @@ describe "Conditions" do
|
|
290
290
|
context "searchlogic lambda" do
|
291
291
|
it "should be a string" do
|
292
292
|
User.username_like("test")
|
293
|
-
User.named_scope_options(:username_like).
|
293
|
+
User.named_scope_options(:username_like).searchlogic_options[:type].should == :string
|
294
294
|
end
|
295
295
|
|
296
296
|
it "should be an integer" do
|
297
297
|
User.id_gt(10)
|
298
|
-
User.named_scope_options(:id_gt).
|
298
|
+
User.named_scope_options(:id_gt).searchlogic_options[:type].should == :integer
|
299
299
|
end
|
300
300
|
|
301
301
|
it "should be a float" do
|
302
302
|
Order.total_gt(10)
|
303
|
-
Order.named_scope_options(:total_gt).
|
303
|
+
Order.named_scope_options(:total_gt).searchlogic_options[:type].should == :float
|
304
304
|
end
|
305
305
|
end
|
306
306
|
|
data/spec/search_spec.rb
CHANGED
@@ -290,6 +290,12 @@ describe "Search" do
|
|
290
290
|
search.created_at_after.should == Time.zone.parse("Jan 1, 2009 9:33AM")
|
291
291
|
end
|
292
292
|
|
293
|
+
it "should skip time zone conversion for attributes skipped" do
|
294
|
+
search = User.search
|
295
|
+
search.whatever_at_after = "Jan 1, 2009 9:33AM"
|
296
|
+
search.whatever_at_after.should == Time.parse("Jan 1, 2009 9:33AM").utc
|
297
|
+
end
|
298
|
+
|
293
299
|
it "should convert the time to the current zone" do
|
294
300
|
search = Order.search
|
295
301
|
now = Time.now
|
data/spec/spec_helper.rb
CHANGED
@@ -42,6 +42,7 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
42
42
|
t.integer :age
|
43
43
|
t.boolean :male
|
44
44
|
t.string :some_type_id
|
45
|
+
t.datetime :whatever_at
|
45
46
|
end
|
46
47
|
|
47
48
|
create_table :carts do |t|
|
@@ -99,6 +100,8 @@ Spec::Runner.configure do |config|
|
|
99
100
|
has_many :orders, :dependent => :destroy
|
100
101
|
has_many :orders_big, :class_name => 'Order', :conditions => 'total > 100'
|
101
102
|
has_and_belongs_to_many :user_groups
|
103
|
+
|
104
|
+
self.skip_time_zone_conversion_for_attributes = [:whatever_at]
|
102
105
|
end
|
103
106
|
|
104
107
|
class Order < ActiveRecord::Base
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 2
|
7
7
|
- 4
|
8
|
-
-
|
9
|
-
version: 2.4.
|
8
|
+
- 13
|
9
|
+
version: 2.4.13
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Ben Johnson of Binary Logic
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-04-04 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|