texticle 2.0.pre4 → 2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -15,13 +15,13 @@ extending ActiveRecord with scopes making search easy and fun!
15
15
 
16
16
  == SYNOPSIS:
17
17
 
18
- === Configuration
18
+ === Quick Start
19
19
 
20
20
  * Rails 3
21
21
 
22
22
  In the project's Gemfile add
23
23
 
24
- gem 'texticle', '~> 2.0.pre', :require => 'texticle/rails'
24
+ gem 'texticle', '~> 2.0', :require => 'texticle/rails'
25
25
 
26
26
  * ActiveRecord outside of Rails 3
27
27
 
@@ -36,6 +36,7 @@ Your models now have access to the search method:
36
36
  Game.search(:title => 'Mario')
37
37
  Game.search_by_title('Street Fighter').search_by_system('PS3')
38
38
  Game.search_by_title_and_system('Final Fantasy', 'PS2')
39
+ Game.search_by_title_or_system('Final Fantasy, 'PS3')
39
40
 
40
41
  == REQUIREMENTS:
41
42
 
@@ -43,7 +44,7 @@ Your models now have access to the search method:
43
44
 
44
45
  == INSTALL:
45
46
 
46
- * gem install texticle --pre
47
+ * gem install texticle
47
48
 
48
49
  == LICENSE:
49
50
 
data/lib/texticle.rb CHANGED
@@ -2,11 +2,9 @@ require 'active_record'
2
2
 
3
3
  module Texticle
4
4
 
5
- def search(query = "")
5
+ def search(query = "", exclusive = true)
6
6
  language = connection.quote('english')
7
7
 
8
- exclusive = true
9
-
10
8
  unless query.is_a?(Hash)
11
9
  exclusive = false
12
10
  query = searchable_columns.inject({}) do |terms, column|
@@ -34,15 +32,16 @@ module Texticle
34
32
  def method_missing(method, *search_terms)
35
33
  return super if self == ActiveRecord::Base
36
34
  if Helper.dynamic_search_method?(method, self.columns)
37
- columns = Helper.dynamic_search_columns(method)
35
+ exclusive = Helper.exclusive_dynamic_search_method?(method, self.columns)
36
+ columns = exclusive ? Helper.exclusive_dynamic_search_columns(method) : Helper.inclusive_dynamic_search_columns(method)
38
37
  metaclass = class << self; self; end
39
38
  metaclass.__send__(:define_method, method) do |*args|
40
39
  query = columns.inject({}) do |query, column|
41
40
  query.merge column => args.shift
42
41
  end
43
- search(query)
42
+ search(query, exclusive)
44
43
  end
45
- __send__(method, *search_terms)
44
+ __send__(method, *search_terms, exclusive)
46
45
  else
47
46
  super
48
47
  end
@@ -69,23 +68,46 @@ module Texticle
69
68
  query.to_s.gsub(' ', '\\\\ ')
70
69
  end
71
70
 
72
- def dynamic_search_columns(method)
73
- if match = method.to_s.match(/search_by_(?<columns>[_a-zA-Z]\w*)/)
71
+ def exclusive_dynamic_search_columns(method)
72
+ if match = method.to_s.match(/^search_by_(?<columns>[_a-zA-Z]\w*)$/)
74
73
  match[:columns].split('_and_')
75
74
  else
76
75
  []
77
76
  end
78
77
  end
79
78
 
80
- def dynamic_search_method?(method, class_columns)
79
+ def inclusive_dynamic_search_columns(method)
80
+ if match = method.to_s.match(/^search_by_(?<columns>[_a-zA-Z]\w*)$/)
81
+ match[:columns].split('_or_')
82
+ else
83
+ []
84
+ end
85
+ end
86
+
87
+ def exclusive_dynamic_search_method?(method, class_columns)
88
+ string_columns = class_columns.select {|column| column.type == :string }.map(&:name)
89
+ columns = exclusive_dynamic_search_columns(method)
90
+ unless columns.empty?
91
+ columns.all? {|column| string_columns.include?(column) }
92
+ else
93
+ false
94
+ end
95
+ end
96
+
97
+ def inclusive_dynamic_search_method?(method, class_columns)
81
98
  string_columns = class_columns.select {|column| column.type == :string }.map(&:name)
82
- columns = dynamic_search_columns(method)
99
+ columns = inclusive_dynamic_search_columns(method)
83
100
  unless columns.empty?
84
101
  columns.all? {|column| string_columns.include?(column) }
85
102
  else
86
103
  false
87
104
  end
88
105
  end
106
+
107
+ def dynamic_search_method?(method, class_columns)
108
+ exclusive_dynamic_search_method?(method, class_columns) or
109
+ inclusive_dynamic_search_method?(method, class_columns)
110
+ end
89
111
  end
90
112
  end
91
113
 
@@ -111,6 +111,10 @@ class TexticleTest < Test::Unit::TestCase
111
111
  assert_equal [@mario], Game.search_by_title_and_title("Mario", "Mario")
112
112
  end
113
113
 
114
+ should "generate methods for inclusive searches" do
115
+ assert_equal Set.new([@megam, @takun]), Game.search_by_system_or_title("Saturn", "Mega Man").to_set
116
+ end
117
+
114
118
  should "scope consecutively" do
115
119
  assert_equal [@sfgen], Game.search_by_system("Genesis").search_by_title("Street Fighter")
116
120
  end
@@ -123,9 +127,11 @@ class TexticleTest < Test::Unit::TestCase
123
127
  assert Game.respond_to?(:search_by_system)
124
128
  assert Game.respond_to?(:search_by_title)
125
129
  assert Game.respond_to?(:search_by_system_and_title)
130
+ assert Game.respond_to?(:search_by_system_or_title)
126
131
  assert Game.respond_to?(:search_by_title_and_title_and_title)
127
132
 
128
133
  assert !Game.respond_to?(:search_by_id)
134
+ assert !Game.respond_to?(:search_by_title_and_title_or_title)
129
135
  end
130
136
 
131
137
  should "allow for 2 arguments to #respond_to?" do
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: texticle
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: 4
5
- version: 2.0.pre4
4
+ prerelease:
5
+ version: "2.0"
6
6
  platform: ruby
7
7
  authors:
8
8
  - ecin
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2011-07-03 00:00:00 Z
14
+ date: 2011-07-10 00:00:00 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: pg