simple_column_search 1.0.4 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,5 @@
1
+ v1.1.0. Support for lambdas on :match and :escape.
2
+
1
3
  v1.0.4. Spew an appropriate error on invalid match type.
2
4
 
3
5
  v1.0.3. General Ruby and Rails 3 compatibility.
data/README.rdoc CHANGED
@@ -11,7 +11,7 @@ Add a search method to your model by calling simple_column_search with the field
11
11
  class User
12
12
  simple_column_search :first_name, :last_name
13
13
  end
14
-
14
+
15
15
  Search for a single value across all searched columns.
16
16
 
17
17
  User.search('eli') # => anyone with first or last name starting with eli
@@ -23,6 +23,24 @@ Refine the search by adding another search term.
23
23
  # => anyone with first or last name starting with eli AND
24
24
  # anyone with first or last name starting with miller
25
25
 
26
+ Specify query match mode. Use :exact, :start, :middle, or :end (default is :start).
27
+
28
+ class User
29
+ simple_column_search :name, :match => :exact
30
+ end
31
+
32
+ Specify query match based on column name.
33
+
34
+ class User
35
+ simple_column_search :name, :email, :match => lambda { |column| column == :email ? :middle : :start },
36
+ end
37
+
38
+ Escape query string before issuing the search request.
39
+
40
+ class User
41
+ simple_column_search :name, :escape => lambda { |query| query.gsub(/[^\w\s\-\.']/, '').strip }
42
+ end
43
+
26
44
  == Install
27
45
 
28
46
  As a Rails plugin.
@@ -2,6 +2,8 @@ require 'rubygems'
2
2
  require 'active_record'
3
3
 
4
4
  module SimpleColumnSearch
5
+ class InvalidMatcher < StandardError; end
6
+
5
7
  # Adds a Model.search('term1 term2') method that searches across SEARCH_COLUMNS
6
8
  # for ANDed TERMS ORed across columns.
7
9
  #
@@ -21,29 +23,39 @@ module SimpleColumnSearch
21
23
  options[:match] ||= :start
22
24
  options[:name] ||= 'search'
23
25
 
24
- # Test options at create time
25
- get_simple_column_pattern(options[:match], 'test')
26
+ unless options[:match].respond_to?(:call) || [ :start, :middle, :end, :exact ].include?(options[:match])
27
+ raise InvalidMatcher, "Unexpected match type: #{options[:match].inspect}"
28
+ end
26
29
 
27
30
  # PostgreSQL LIKE is case-sensitive, use ILIKE for case-insensitive
28
31
  like = connection.adapter_name == "PostgreSQL" ? "ILIKE" : "LIKE"
29
- # Determine if ActiveRecord 3 or ActiveRecord 2.3 - probaly beter way to do it!
30
- if self.respond_to?(:where)
32
+ # Determine if ActiveRecord 3
33
+ if ActiveRecord::VERSION::MAJOR == 3
31
34
  scope options[:name], lambda { |terms|
35
+ terms = options[:escape].call(terms) if options[:escape]
32
36
  conditions = terms.split.inject(where(nil)) do |acc, term|
33
- pattern = get_simple_column_pattern options[:match], term
34
- acc.where(columns.collect { |column| "#{table_name}.#{column} #{like} :pattern" }.join(' OR '), { :pattern => pattern })
37
+ patterns = build_simple_column_patterns(columns, options[:match], term)
38
+ acc.where(columns.map { |column| "#{table_name}.#{column} #{like} ?" }.join(' OR '), *patterns)
35
39
  end
36
40
  }
37
41
  else
38
42
  named_scope options[:name], lambda { |terms|
43
+ terms = options[:escape].call(terms) if options[:escape]
39
44
  conditions = terms.split.inject(nil) do |acc, term|
40
- pattern = get_simple_column_pattern options[:match], term
41
- merge_conditions acc, [columns.collect { |column| "#{table_name}.#{column} #{like} :pattern" }.join(' OR '), { :pattern => pattern }]
45
+ patterns = build_simple_column_patterns(columns, options[:match], term)
46
+ merge_conditions acc, [ columns.map { |column| "#{table_name}.#{column} #{like} ?" }.join(' OR '), *patterns ]
42
47
  end
43
48
  { :conditions => conditions }
44
49
  }
45
50
  end
51
+ end
52
+
53
+ private
46
54
 
55
+ def build_simple_column_patterns(columns, match, term)
56
+ columns.map do |column|
57
+ get_simple_column_pattern(match.respond_to?(:call) ? match.call(column) : match, term)
58
+ end
47
59
  end
48
60
 
49
61
  def get_simple_column_pattern(match, term)
@@ -57,12 +69,9 @@ module SimpleColumnSearch
57
69
  when :end
58
70
  '%' + term
59
71
  else
60
- raise InvalidMatcher, "Unexpected match type: #{match}"
72
+ raise InvalidMatcher, "Unexpected match type: #{match.inspect}"
61
73
  end
62
74
  end
63
-
64
- class InvalidMatcher < StandardError; end
65
-
66
75
  end
67
76
 
68
77
  ActiveRecord::Base.extend(SimpleColumnSearch)
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{simple_column_search}
5
- s.version = "1.0.4"
5
+ s.version = "1.1.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Elijah Miller"]
9
- s.date = %q{2010-09-21}
9
+ s.date = %q{2010-10-03}
10
10
  s.description = %q{Quick and dirty multi column LIKE searches.}
11
11
  s.email = %q{elijah.miller@gmail.com}
12
12
  s.extra_rdoc_files = ["CHANGELOG", "lib/simple_column_search.rb", "README.rdoc"]
data/spec/models.rb CHANGED
@@ -7,4 +7,7 @@ class Person < ActiveRecord::Base
7
7
  simple_column_search :first_name, :name => :search_first_name_start, :match => :start
8
8
  simple_column_search :first_name, :name => :search_first_name_middle, :match => :middle
9
9
  simple_column_search :first_name, :name => :search_first_name_end, :match => :end
10
+
11
+ simple_column_search :first_name, :last_name, :name => :search_escape_query, :match => :exact, :escape => lambda { |q| q.strip.split(/\s/).map(&:singularize).join(' ') }
12
+ simple_column_search :first_name, :last_name, :name => :search_match_lambda, :match => lambda { |c| c == :last_name ? :exact : :start }
10
13
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_column_search
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
+ - 1
8
9
  - 0
9
- - 4
10
- version: 1.0.4
10
+ version: 1.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Elijah Miller
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-09-21 00:00:00 -04:00
18
+ date: 2010-10-03 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies: []
21
21