rails-simple-search 0.9.6 → 0.9.7

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.
Files changed (3) hide show
  1. data/lib/rails-simple-search.rb +26 -146
  2. data/lib/sql_handler.rb +146 -0
  3. metadata +3 -1
@@ -1,3 +1,5 @@
1
+ require_relative 'sql_handler'
2
+
1
3
  module RailsSimpleSearch
2
4
  DEFAULT_CONFIG = { :exact_match => [],
3
5
  :paginate => true,
@@ -17,12 +19,20 @@ module RailsSimpleSearch
17
19
  end
18
20
 
19
21
  def initialize(model_class, criteria={}, config={})
20
- @model_class = (model_class.is_a?(Symbol) || model_class.is_a?(String))? model_class.to_s.camelize.constantize : model_class
21
- @table_name = @model_class.table_name
22
- @criteria = criteria.nil? ? {} : criteria
23
- sanitize_criteria
22
+ @criteria = sanitize_criteria(criteria)
24
23
  @config = DEFAULT_CONFIG.merge(config)
25
- @joins = {}
24
+
25
+ @model_class = (model_class.is_a?(Symbol) || model_class.is_a?(String))? model_class.to_s.camelize.constantize : model_class
26
+ load_database_handler(@model_class)
27
+ init
28
+ end
29
+
30
+ def load_database_handler(model_class)
31
+ if model_class.ancestors.include?(ActiveRecord::Base)
32
+ RailsSimpleSearch::Base.send(:include, RailsSimpleSearch::SqlHandler)
33
+ else
34
+ raise("RailsSimpleSearch only supports ActiveRecord for now")
35
+ end
26
36
  end
27
37
 
28
38
  def count
@@ -37,50 +47,16 @@ module RailsSimpleSearch
37
47
  (1..pages).to_a
38
48
  end
39
49
 
40
- def add_conditions(h={})
41
- @criteria.merge!(h)
42
- end
43
-
44
50
  def order=(str)
45
51
  @order = str
46
52
  end
47
53
 
48
- def conditions
49
- run_criteria
50
- @conditions
51
- end
52
-
53
- def joins
54
- run_criteria
55
- @joins_str
56
- end
57
-
58
- def run
59
- run_criteria
60
- if @config[:paginate]
61
- @count = @model_class.count({:select => "distinct #{@model_class.table_name}.#{@model_class.primary_key}",
62
- :conditions => @conditions,
63
- :joins => @joins_str }
64
- )
65
- offset = [((@page || 0) - 1) * @config[:per_page], 0].max
66
- limit = @config[:per_page]
67
- else
68
- offset = @config[:offset]
69
- limit = @config[:limit]
70
- end
71
-
72
- execute_hash = {:select => "distinct #{@model_class.table_name}.*",
73
- :conditions => @conditions,
74
- :joins => @joins_str,
75
- :offset => offset,
76
- :limit => limit
77
- }
78
- execute_hash[:order] = @order if @order
79
- @model_class.all(execute_hash)
54
+ def add_conditions(h={})
55
+ @criteria.merge!(h)
80
56
  end
81
-
82
- private
83
57
 
58
+ private
59
+
84
60
  def method_missing(method, *args)
85
61
  method_str = method.to_s
86
62
  if method_str =~ /^([^=]+)=$/
@@ -89,31 +65,6 @@ module RailsSimpleSearch
89
65
  @criteria[method_str]
90
66
  end
91
67
  end
92
-
93
- def make_joins
94
- @joins_str = ''
95
- joins = @joins.values
96
- joins.sort! {|a,b| a[0] <=> b[0]}
97
- joins.each do |j|
98
- table = j[1]
99
- constrain = j[2]
100
- @joins_str << " inner join #{table} on #{constrain}"
101
- end
102
- end
103
-
104
- def run_criteria
105
- return unless @conditions.nil?
106
- @criteria.each do |key, value|
107
- if @config[:page_name].to_s == key.to_s
108
- @page = value.to_i
109
- @criteria[key] = @page
110
- else
111
- parse_attribute(key, value)
112
- end
113
- end
114
-
115
- make_joins
116
- end
117
68
 
118
69
  def parse_field_name(name)
119
70
  result = {}
@@ -132,87 +83,16 @@ module RailsSimpleSearch
132
83
  end
133
84
  result
134
85
  end
135
-
136
-
137
- def insert_condition(base_class, attribute, field, value)
138
- name_hash = parse_field_name(field)
139
- field = name_hash[:field_name]
140
- operator = name_hash[:operator]
141
-
142
- table = base_class.table_name
143
- key = "#{table}.#{field}"
144
-
145
- @conditions ||= []
146
- column = base_class.columns_hash[field.to_s]
147
-
148
- if !column.text? && value.is_a?(String)
149
- value = column.type_cast(value)
150
- @criteria[attribute] = value
151
- end
152
-
153
- if value.nil?
154
- verb = 'is'
155
- elsif operator
156
- verb = operator
157
- elsif column.text? && ! @config[:exact_match].include?((@table_name == table)? field : key)
158
- verb = 'like'
159
- value = "%#{value}%"
160
- else
161
- verb = '='
162
- end
163
-
164
- if @conditions.size < 1
165
- @conditions[0] = "#{key} #{verb} ?"
166
- @conditions[1] = value
167
- else
168
- @conditions[0] += " and #{key} #{verb} ?"
169
- @conditions << value
170
- end
171
- end
172
-
173
- def insert_join(base_class, asso_ref)
174
- base_table = base_class.table_name
175
- asso_table = asso_ref.klass.table_name
176
-
177
- @join_count ||= 0
178
- unless base_table == asso_table
179
- if @joins[asso_table].nil?
180
- @join_count += 1
181
- if asso_ref.belongs_to?
182
- @joins[asso_table] =[@join_count, asso_table, "#{base_table}.#{asso_ref.foreign_key} = #{asso_table}.#{asso_ref.klass.primary_key}"]
183
- else
184
- @joins[asso_table] = [@join_count, asso_table, "#{base_table}.#{base_class.primary_key} = #{asso_table}.#{asso_ref.foreign_key}"]
185
- end
186
- end
187
- end
188
- end
189
-
190
- def parse_attribute(attribute, value)
191
- unless attribute =~ /\./
192
- field = attribute
193
- insert_condition(@model_class, attribute, field, value)
194
- return
195
- end
196
-
197
- association_fields = attribute.split(/\./)
198
- field = association_fields.pop
199
-
200
- base_class = @model_class
201
- while (association_fields.size > 0)
202
- association_fields[0] = base_class.reflect_on_association(association_fields[0].to_sym)
203
- insert_join(base_class, association_fields[0])
204
- base_class = association_fields.shift.klass
205
- end
206
-
207
- insert_condition(base_class, attribute, field, value)
208
- end
209
86
 
210
- def sanitize_criteria
211
- @criteria.keys.each do |key|
212
- if @criteria[key].nil? || @criteria[key].blank?
213
- @criteria.delete(key)
87
+ def sanitize_criteria(criteria)
88
+ criteria = criteria || {}
89
+ c = {}
90
+ criteria.each do |key, value|
91
+ unless value.blank?
92
+ c[key] = value
214
93
  end
215
94
  end
95
+ c
216
96
  end
217
97
  end
218
98
  end
@@ -0,0 +1,146 @@
1
+ module RailsSimpleSearch
2
+ module SqlHandler
3
+
4
+ def init
5
+ @table_name = @model_class.table_name
6
+ @joins = {}
7
+ end
8
+
9
+ def conditions
10
+ run_criteria
11
+ @conditions
12
+ end
13
+
14
+ def joins
15
+ run_criteria
16
+ @joins_str
17
+ end
18
+
19
+ def run
20
+ run_criteria
21
+ if @config[:paginate]
22
+ @count = @model_class.count({:select => "distinct #{@model_class.table_name}.#{@model_class.primary_key}",
23
+ :conditions => @conditions,
24
+ :joins => @joins_str }
25
+ )
26
+ offset = [((@page || 0) - 1) * @config[:per_page], 0].max
27
+ limit = @config[:per_page]
28
+ else
29
+ offset = @config[:offset]
30
+ limit = @config[:limit]
31
+ end
32
+
33
+ execute_hash = {:select => "distinct #{@model_class.table_name}.*",
34
+ :conditions => @conditions,
35
+ :joins => @joins_str,
36
+ :offset => offset,
37
+ :limit => limit
38
+ }
39
+ execute_hash[:order] = @order if @order
40
+ @model_class.all(execute_hash)
41
+ end
42
+
43
+ private
44
+
45
+ def make_joins
46
+ @joins_str = ''
47
+ joins = @joins.values
48
+ joins.sort! {|a,b| a[0] <=> b[0]}
49
+ joins.each do |j|
50
+ table = j[1]
51
+ constrain = j[2]
52
+ @joins_str << " inner join #{table} on #{constrain}"
53
+ end
54
+ end
55
+
56
+ def run_criteria
57
+ return unless @conditions.nil?
58
+ @criteria.each do |key, value|
59
+ if @config[:page_name].to_s == key.to_s
60
+ @page = value.to_i
61
+ @criteria[key] = @page
62
+ else
63
+ parse_attribute(key, value)
64
+ end
65
+ end
66
+
67
+ make_joins
68
+ end
69
+
70
+ def insert_condition(base_class, attribute, field, value)
71
+ name_hash = parse_field_name(field)
72
+ field = name_hash[:field_name]
73
+ operator = name_hash[:operator]
74
+
75
+ table = base_class.table_name
76
+ key = "#{table}.#{field}"
77
+
78
+ @conditions ||= []
79
+ column = base_class.columns_hash[field.to_s]
80
+
81
+ if !column.text? && value.is_a?(String)
82
+ value = column.type_cast(value)
83
+ @criteria[attribute] = value
84
+ end
85
+
86
+ if value.nil?
87
+ verb = 'is'
88
+ elsif operator
89
+ verb = operator
90
+ elsif column.text? && ! @config[:exact_match].include?((@table_name == table)? field : key)
91
+ verb = 'like'
92
+ value = "%#{value}%"
93
+ else
94
+ verb = '='
95
+ end
96
+
97
+ if @conditions.size < 1
98
+ @conditions[0] = "#{key} #{verb} ?"
99
+ @conditions[1] = value
100
+ else
101
+ @conditions[0] += " and #{key} #{verb} ?"
102
+ @conditions << value
103
+ end
104
+ end
105
+
106
+ def insert_join(base_class, asso_ref)
107
+ base_table = base_class.table_name
108
+ asso_table = asso_ref.klass.table_name
109
+
110
+ @join_count ||= 0
111
+ unless base_table == asso_table
112
+ if @joins[asso_table].nil?
113
+ @join_count += 1
114
+ if asso_ref.belongs_to?
115
+ @joins[asso_table] =[@join_count, asso_table, "#{base_table}.#{asso_ref.foreign_key} = #{asso_table}.#{asso_ref.klass.primary_key}"]
116
+ else
117
+ join_cond = "#{base_table}.#{base_class.primary_key} = #{asso_table}.#{asso_ref.foreign_key}"
118
+ join_cond = "#{asso_table}.#{asso_ref.type} = '#{base_class.name}' and #{join_cond}" if asso_ref.type
119
+ @joins[asso_table] = [@join_count, asso_table, join_cond]
120
+ end
121
+ end
122
+ end
123
+ end
124
+
125
+ def parse_attribute(attribute, value)
126
+ unless attribute =~ /\./
127
+ field = attribute
128
+ insert_condition(@model_class, attribute, field, value)
129
+ return
130
+ end
131
+
132
+ association_fields = attribute.split(/\./)
133
+ field = association_fields.pop
134
+
135
+ base_class = @model_class
136
+ while (association_fields.size > 0)
137
+ association_fields[0] = base_class.reflect_on_association(association_fields[0].to_sym)
138
+ insert_join(base_class, association_fields[0])
139
+ base_class = association_fields.shift.klass
140
+ end
141
+
142
+ insert_condition(base_class, attribute, field, value)
143
+ end
144
+
145
+ end
146
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-simple-search
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.6
4
+ version: 0.9.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -20,6 +20,7 @@ extra_rdoc_files: []
20
20
  files:
21
21
  - README.rdoc
22
22
  - lib/rails-simple-search.rb
23
+ - lib/sql_handler.rb
23
24
  homepage: http://github.com/yzhanginwa/rails-simple-search
24
25
  licenses: []
25
26
  post_install_message:
@@ -45,3 +46,4 @@ signing_key:
45
46
  specification_version: 3
46
47
  summary: A very simple and light get to quick build search function in rails
47
48
  test_files: []
49
+ has_rdoc: