texticle 2.0.pre4 → 2.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/README.rdoc +4 -3
- data/lib/texticle.rb +32 -10
- data/spec/texticle_spec.rb +6 -0
- metadata +3 -3
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
|
-
===
|
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
|
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
|
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
|
-
|
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
|
73
|
-
if match = method.to_s.match(
|
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
|
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 =
|
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
|
|
data/spec/texticle_spec.rb
CHANGED
@@ -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:
|
5
|
-
version: 2.0
|
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-
|
14
|
+
date: 2011-07-10 00:00:00 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: pg
|