Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Escape wildcard characters in LIKE clause
  • Loading branch information
labocho committed Nov 26, 2012
1 parent 3542cf4 commit fad3ac9
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 6 deletions.
18 changes: 12 additions & 6 deletions lib/ransack/constants.rb
Expand Up @@ -6,18 +6,24 @@ module Constants
AREL_PREDICATES = %w(eq not_eq matches does_not_match lt lteq gt gteq in not_in)

DERIVED_PREDICATES = [
['cont', {:arel_predicate => 'matches', :formatter => proc {|v| "%#{v}%"}}],
['not_cont', {:arel_predicate => 'does_not_match', :formatter => proc {|v| "%#{v}%"}}],
['start', {:arel_predicate => 'matches', :formatter => proc {|v| "#{v}%"}}],
['not_start', {:arel_predicate => 'does_not_match', :formatter => proc {|v| "#{v}%"}}],
['end', {:arel_predicate => 'matches', :formatter => proc {|v| "%#{v}"}}],
['not_end', {:arel_predicate => 'does_not_match', :formatter => proc {|v| "%#{v}"}}],
['cont', {:arel_predicate => 'matches', :formatter => proc {|v| "%#{escape_wildcards(v)}%"}}],
['not_cont', {:arel_predicate => 'does_not_match', :formatter => proc {|v| "%#{escape_wildcards(v)}%"}}],
['start', {:arel_predicate => 'matches', :formatter => proc {|v| "#{escape_wildcards(v)}%"}}],
['not_start', {:arel_predicate => 'does_not_match', :formatter => proc {|v| "#{escape_wildcards(v)}%"}}],
['end', {:arel_predicate => 'matches', :formatter => proc {|v| "%#{escape_wildcards(v)}"}}],
['not_end', {:arel_predicate => 'does_not_match', :formatter => proc {|v| "%#{escape_wildcards(v)}"}}],
['true', {:arel_predicate => 'eq', :compounds => false, :type => :boolean, :validator => proc {|v| TRUE_VALUES.include?(v)}}],
['false', {:arel_predicate => 'eq', :compounds => false, :type => :boolean, :validator => proc {|v| TRUE_VALUES.include?(v)}, :formatter => proc {|v| !v}}],
['present', {:arel_predicate => 'not_eq_all', :compounds => false, :type => :boolean, :validator => proc {|v| TRUE_VALUES.include?(v)}, :formatter => proc {|v| [nil, '']}}],
['blank', {:arel_predicate => 'eq_any', :compounds => false, :type => :boolean, :validator => proc {|v| TRUE_VALUES.include?(v)}, :formatter => proc {|v| [nil, '']}}],
['null', {:arel_predicate => 'eq', :compounds => false, :type => :boolean, :validator => proc {|v| TRUE_VALUES.include?(v)}, :formatter => proc {|v| nil}}],
['not_null', {:arel_predicate => 'not_eq', :compounds => false, :type => :boolean, :validator => proc {|v| TRUE_VALUES.include?(v)}, :formatter => proc {|v| nil}}]
]

module_function
# replace % _ \ to \% \_ \\
def escape_wildcards(unescaped)
unescaped.gsub(/\\/){ "\\\\" }.gsub(/%/, "\\%").gsub(/_/, "\\_")
end
end
end
4 changes: 4 additions & 0 deletions spec/ransack/predicate_spec.rb
Expand Up @@ -29,6 +29,10 @@ module Ransack
@s.name_cont = 'ric'
@s.result.to_sql.should match /"people"."name" LIKE '%ric%'/
end
it 'escapes %, _ and \\ in value' do
@s.name_cont = '%_\\'
@s.result.to_sql.should match /"people"."name" LIKE '%\\%\\_\\\\%'/
end
end

describe 'not_cont' do
Expand Down

0 comments on commit fad3ac9

Please sign in to comment.