simple_column_search 1.0.4 → 1.1.0

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/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