Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Revert recent blank condition changes. Include blank conditions when …

…calling the conditions method, everything else is as it was.
  • Loading branch information...
commit 5fae869d04e16b25cf0f41425f4588ab02935855 1 parent 0bcdfdd
Ben Johnson yourewelcome authored

Showing 2 changed files with 51 additions and 73 deletions. Show diff stats Hide diff stats

  1. +42 51 lib/searchlogic/search.rb
  2. +9 22 spec/search_spec.rb
93 lib/searchlogic/search.rb
@@ -47,6 +47,7 @@ def initialize(condition)
47 47 def initialize(klass, current_scope, conditions = {})
48 48 self.klass = klass
49 49 self.current_scope = current_scope
  50 + @conditions ||= {}
50 51 self.conditions = conditions if conditions.is_a?(Hash)
51 52 end
52 53
@@ -56,18 +57,17 @@ def clone
56 57
57 58 # Returns a hash of the current conditions set.
58 59 def conditions
59   - @conditions ||= {}
  60 + mass_conditions.clone.merge(@conditions)
60 61 end
61 62
62 63 # Accepts a hash of conditions.
63 64 def conditions=(values)
64   - @setting_mass_conditions = true
65   - result = values.each do |condition, value|
  65 + values.each do |condition, value|
66 66 mass_conditions[condition.to_sym] = value
  67 + value.delete_if { |v| ignore_value?(v) } if value.is_a?(Array)
  68 + next if ignore_value?(value)
67 69 send("#{condition}=", value)
68 70 end
69   - @setting_mass_conditions = false
70   - result
71 71 end
72 72
73 73 # Delete a condition from the search. Since conditions map to named scopes,
@@ -86,19 +86,17 @@ def method_missing(name, *args, &block)
86 86
87 87 if setter?(name)
88 88 if scope?(scope_name)
89   - mass_conditions.delete(scope_name.to_sym) if !setting_mass_conditions?
90   -
91 89 if args.size == 1
92   - conditions[condition_name] = type_cast(args.first, cast_type(scope_name))
  90 + write_condition(condition_name, type_cast(args.first, cast_type(scope_name)))
93 91 else
94   - conditions[condition_name] = args
  92 + write_condition(condition_name, args)
95 93 end
96 94 else
97 95 raise UnknownConditionError.new(condition_name)
98 96 end
99 97 elsif scope?(scope_name) && args.size <= 1
100 98 if args.size == 0
101   - conditions[condition_name]
  99 + read_condition(condition_name)
102 100 else
103 101 send("#{condition_name}=", *args)
104 102 self
@@ -106,27 +104,20 @@ def method_missing(name, *args, &block)
106 104 else
107 105 scope = conditions_array.inject(klass.scoped(current_scope) || {}) do |scope, condition|
108 106 scope_name, value = condition
  107 + scope_name = normalize_scope_name(scope_name)
  108 + klass.send(scope_name, value) if !klass.respond_to?(scope_name)
  109 + arity = klass.named_scope_arity(scope_name)
109 110
110   - value.delete_if { |v| ignore_value?(v) } if mass_conditions.key?(scope_name.to_sym) && value.is_a?(Array)
111   -
112   - if mass_conditions.key?(scope_name.to_sym) && ignore_value?(value)
113   - klass.scoped({})
114   - else
115   - scope_name = normalize_scope_name(scope_name)
116   - klass.send(scope_name, value) if !klass.respond_to?(scope_name)
117   - arity = klass.named_scope_arity(scope_name)
118   -
119   - if !arity || arity == 0
120   - if value == true
121   - scope.send(scope_name)
122   - else
123   - scope
124   - end
125   - elsif arity == -1
126   - scope.send(scope_name, *(value.is_a?(Array) ? value : [value]))
  111 + if !arity || arity == 0
  112 + if value == true
  113 + scope.send(scope_name)
127 114 else
128   - scope.send(scope_name, value)
  115 + scope
129 116 end
  117 + elsif arity == -1
  118 + scope.send(scope_name, *(value.is_a?(Array) ? value : [value]))
  119 + else
  120 + scope.send(scope_name, value)
130 121 end
131 122 end
132 123 scope.send(name, *args, &block)
@@ -155,6 +146,18 @@ def condition_name(name)
155 146 condition ? condition[1].to_sym : nil
156 147 end
157 148
  149 + def write_condition(name, value)
  150 + @conditions[name] = value
  151 + end
  152 +
  153 + def read_condition(name)
  154 + @conditions[name]
  155 + end
  156 +
  157 + def mass_conditions
  158 + @mass_conditions ||= {}
  159 + end
  160 +
158 161 def scope_name(condition_name)
159 162 condition_name && normalize_scope_name(condition_name)
160 163 end
@@ -174,14 +177,6 @@ def cast_type(name)
174 177 end
175 178 end
176 179
177   - def mass_conditions
178   - @mass_conditions ||= {}
179   - end
180   -
181   - def setting_mass_conditions?
182   - @setting_mass_conditions == true
183   - end
184   -
185 180 def type_cast(value, type)
186 181 case value
187 182 when Array
@@ -189,24 +184,20 @@ def type_cast(value, type)
189 184 when Range
190 185 Range.new(type_cast(value.first, type), type_cast(value.last, type))
191 186 else
192   - if setting_mass_conditions? && ignore_value?(value)
193   - value
194   - else
195   - # Let's leverage ActiveRecord's type casting, so that casting is consistent
196   - # with the other models.
197   - column_for_type_cast = ::ActiveRecord::ConnectionAdapters::Column.new("", nil)
198   - column_for_type_cast.instance_variable_set(:@type, type)
199   - casted_value = column_for_type_cast.type_cast(value)
  187 + # Let's leverage ActiveRecord's type casting, so that casting is consistent
  188 + # with the other models.
  189 + column_for_type_cast = ::ActiveRecord::ConnectionAdapters::Column.new("", nil)
  190 + column_for_type_cast.instance_variable_set(:@type, type)
  191 + casted_value = column_for_type_cast.type_cast(value)
200 192
201   - if Time.zone && casted_value.is_a?(Time)
202   - if value.is_a?(String)
203   - (casted_value + (Time.zone.utc_offset * -1)).in_time_zone
204   - else
205   - casted_value.in_time_zone
206   - end
  193 + if Time.zone && casted_value.is_a?(Time)
  194 + if value.is_a?(String)
  195 + (casted_value + (Time.zone.utc_offset * -1)).in_time_zone
207 196 else
208   - casted_value
  197 + casted_value.in_time_zone
209 198 end
  199 + else
  200 + casted_value
210 201 end
211 202 end
212 203 end
31 spec/search_spec.rb
@@ -80,22 +80,27 @@
80 80
81 81 # We ignore them upon execution. But we still want to accept the condition so that returning the conditions
82 82 # preserves the values.
83   - it "should not ignore blank values" do
  83 + it "should ignore blank values but still return on conditions" do
84 84 search = User.search
85 85 search.conditions = {"username" => ""}
86   - search.username.should == ""
  86 + search.username.should be_nil
  87 + search.conditions.should == {:username => ""}
87 88 end
88 89
89 90 it "should not ignore blank values and should not cast them" do
90 91 search = User.search
91 92 search.conditions = {"id_equals" => ""}
92   - search.id_equals.should == ""
  93 + search.id_equals.should be_nil
  94 + search.conditions.should == {:id_equals => ""}
93 95 end
94 96
95 97 it "should ignore blank values in arrays" do
96 98 search = User.search
97 99 search.conditions = {"username_equals_any" => [""]}
98   - search.username_equals_any.first.should be_blank
  100 + search.username_equals_any.should be_nil
  101 +
  102 + search.conditions = {"id_equals_any" => ["", "1"]}
  103 + search.id_equals_any.should == [1]
99 104 end
100 105 end
101 106
@@ -375,24 +380,6 @@
375 380 s.created_at_after = Time.now
376 381 lambda { s.count }.should_not raise_error
377 382 end
378   -
379   - it "should ignore blank values" do
380   - search = User.search
381   - search.conditions = {"username_equals" => ""}
382   - search.proxy_options.should == {}
383   - end
384   -
385   - it "should not ignore blank values when explicitly set" do
386   - search = User.search
387   - search.username_equals = ""
388   - search.proxy_options.should == {:conditions => ["users.username = ?", ""]}
389   - end
390   -
391   - it "should ignore blank values in arrays" do
392   - search = User.search
393   - search.conditions = {"username_equals_any" => [""]}
394   - search.proxy_options.should == {}
395   - end
396 383 end
397 384
398 385 context "method delegation" do

0 comments on commit 5fae869

Please sign in to comment.
Something went wrong with that request. Please try again.