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 CHANGED
@@ -2,4 +2,4 @@
2
2
  :major: 2
3
3
  :build:
4
4
  :minor: 4
5
- :patch: 12
5
+ :patch: 13
@@ -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.searchlogic_arg_type = type
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 :searchlogic_arg_type
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?(:searchlogic_arg_type) && scope_options.searchlogic_arg_type) || :string
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, value_modifier = nil)
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?(:searchlogic_arg_type) ? scope.searchlogic_arg_type : :string
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
  }
@@ -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(condition_name, type_cast(args.first, cast_type(scope_name)))
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 cast_type(name)
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
- named_scope_options = klass.named_scope_options(name)
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?(:searchlogic_arg_type) ? named_scope_options.searchlogic_arg_type : :string
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
- (casted_value + (Time.zone.utc_offset * -1)).in_time_zone
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.12"
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-03-09}
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 searchlogic_arg_type" do
5
- searchlogic_lambda(:integer) {}.searchlogic_arg_type.should == :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
@@ -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 searchlogic_arg_type accessor" do
4
+ it "should have a searchlogic_options accessor" do
5
5
  p = Proc.new {}
6
- p.searchlogic_arg_type = :integer
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).searchlogic_arg_type.should == :string
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).searchlogic_arg_type.should == :integer
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).searchlogic_arg_type.should == :float
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
- - 12
9
- version: 2.4.12
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-03-09 00:00:00 -08:00
17
+ date: 2010-04-04 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency