Skip to content

Commit

Permalink
Blank values should be stored in the conditions hash and ignored when…
Browse files Browse the repository at this point in the history
… taking action, ONLY if those blank values were mass set. If they were explicitly set, the should not be ignored
  • Loading branch information
binarylogic committed Feb 3, 2010
1 parent ccb29a6 commit a8aafc9
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 19 deletions.
1 change: 0 additions & 1 deletion Rakefile
Expand Up @@ -14,7 +14,6 @@ begin
gem.add_dependency "activerecord", ">= 2.0.0"
end
Jeweler::GemcutterTasks.new
Jeweler::RubyforgeTasks.new
rescue LoadError
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
end
Expand Down
47 changes: 32 additions & 15 deletions lib/searchlogic/search.rb
Expand Up @@ -61,11 +61,13 @@ def conditions

# Accepts a hash of conditions.
def conditions=(values)
values.each do |condition, value|
value.delete_if { |v| ignore_value?(v) } if value.is_a?(Array)
next if ignore_value?(value)
@setting_mass_conditions = true
result = values.each do |condition, value|
mass_conditions[condition.to_sym] = value
send("#{condition}=", value)
end
@setting_mass_conditions = false
result
end

# Delete a condition from the search. Since conditions map to named scopes,
Expand All @@ -84,6 +86,7 @@ def method_missing(name, *args, &block)

if setter?(name)
if scope?(scope_name)
mass_conditions.delete(scope_name.to_sym) if !setting_mass_conditions?
if args.size == 1
conditions[condition_name] = type_cast(args.first, cast_type(scope_name))
else
Expand All @@ -102,20 +105,26 @@ def method_missing(name, *args, &block)
else
scope = conditions_array.inject(klass.scoped(current_scope) || {}) do |scope, condition|
scope_name, value = condition
scope_name = normalize_scope_name(scope_name)
klass.send(scope_name, value) if !klass.respond_to?(scope_name)
arity = klass.named_scope_arity(scope_name)

if !arity || arity == 0
if value == true
scope.send(scope_name)
value.delete_if { |v| ignore_value?(scope_name, v) } if value.is_a?(Array)
if !ignore_value?(scope_name, value)
scope_name = normalize_scope_name(scope_name)
klass.send(scope_name, value) if !klass.respond_to?(scope_name)
arity = klass.named_scope_arity(scope_name)

if !arity || arity == 0
if value == true
scope.send(scope_name)
else
scope
end
elsif arity == -1
scope.send(scope_name, *(value.is_a?(Array) ? value : [value]))
else
scope
scope.send(scope_name, value)
end
elsif arity == -1
scope.send(scope_name, *(value.is_a?(Array) ? value : [value]))
else
scope.send(scope_name, value)
klass.scoped({})
end
end
scope.send(name, *args, &block)
Expand Down Expand Up @@ -163,6 +172,14 @@ def cast_type(name)
end
end

def mass_conditions
@mass_conditions ||= {}
end

def setting_mass_conditions?
@setting_mass_conditions == true
end

def type_cast(value, type)
case value
when Array
Expand All @@ -188,8 +205,8 @@ def type_cast(value, type)
end
end

def ignore_value?(value)
(value.is_a?(String) && value.blank?) || (value.is_a?(Array) && value.empty?)
def ignore_value?(scope_name, value)
mass_conditions.key?(scope_name.to_sym) && (value.is_a?(String) && value.blank?) || (value.is_a?(Array) && value.empty?)
end
end
end
26 changes: 23 additions & 3 deletions spec/search_spec.rb
Expand Up @@ -69,10 +69,12 @@
search.username.should == "bjohnson"
end

it "should ignore blank values" do
# We ignore them upon execution. But we still want to accept the condition so that returning the conditions
# preserves the values.
it "should not ignore blank values" do
search = User.search
search.conditions = {"username" => ""}
search.username.should be_nil
search.username.should == ""
end

it "should use custom scopes before normalizing" do
Expand All @@ -87,7 +89,7 @@
it "should ignore blank values in arrays" do
search = User.search
search.conditions = {"username_equals_any" => [""]}
search.username_equals_any.should be_blank
search.username_equals_any.first.should be_blank
end
end

Expand Down Expand Up @@ -361,6 +363,24 @@
s.created_at_after = Time.now
lambda { s.count }.should_not raise_error
end

it "should ignore blank values" do
search = User.search
search.conditions = {"username_equals" => ""}
search.proxy_options.should == {}
end

it "should not ignore blank values when explicitly set" do
search = User.search
search.username_equals = ""
search.proxy_options.should == {:conditions => ["users.username = ?", ""]}
end

it "should ignore blank values in arrays" do
search = User.search
search.conditions = {"username_equals_any" => [""]}
search.proxy_options.should == {}
end
end

context "method delegation" do
Expand Down

0 comments on commit a8aafc9

Please sign in to comment.