searchlogic 2.4.12 → 2.4.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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