hobo 0.7.3 → 0.7.4
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/hobo +1 -1
- data/hobo_files/plugin/CHANGES.txt +302 -0
- data/hobo_files/plugin/generators/hobo_front_controller/templates/index.dryml +2 -9
- data/hobo_files/plugin/generators/hobo_model/templates/model.rb +1 -1
- data/hobo_files/plugin/generators/hobo_model_resource/hobo_model_resource_generator.rb +0 -2
- data/hobo_files/plugin/generators/hobo_rapid/templates/hobo-rapid.js +76 -46
- data/hobo_files/plugin/generators/hobo_rapid/templates/lowpro.js +25 -18
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/application.css +29 -11
- data/hobo_files/plugin/generators/hobo_user_model/templates/model.rb +2 -2
- data/hobo_files/plugin/init.rb +0 -1
- data/hobo_files/plugin/lib/active_record/has_many_association.rb +3 -0
- data/hobo_files/plugin/lib/hobo.rb +12 -8
- data/hobo_files/plugin/lib/hobo/bundle.rb +1 -1
- data/hobo_files/plugin/lib/hobo/dryml/dryml_builder.rb +1 -1
- data/hobo_files/plugin/lib/hobo/dryml/parser/attribute.rb +41 -0
- data/hobo_files/plugin/lib/hobo/dryml/parser/base_parser.rb +253 -0
- data/hobo_files/plugin/lib/hobo/dryml/parser/document.rb +26 -0
- data/hobo_files/plugin/lib/hobo/dryml/parser/element.rb +27 -0
- data/hobo_files/plugin/lib/hobo/dryml/parser/elements.rb +45 -0
- data/hobo_files/plugin/lib/hobo/dryml/parser/source.rb +58 -0
- data/hobo_files/plugin/lib/hobo/dryml/parser/text.rb +13 -0
- data/hobo_files/plugin/lib/hobo/dryml/parser/tree_parser.rb +67 -0
- data/hobo_files/plugin/lib/hobo/dryml/scoped_variables.rb +10 -5
- data/hobo_files/plugin/lib/hobo/dryml/template.rb +48 -27
- data/hobo_files/plugin/lib/hobo/dryml/template_environment.rb +28 -13
- data/hobo_files/plugin/lib/hobo/hobo_helper.rb +3 -1
- data/hobo_files/plugin/lib/hobo/model.rb +70 -10
- data/hobo_files/plugin/lib/hobo/model_controller.rb +49 -34
- data/hobo_files/plugin/lib/hobo/model_router.rb +10 -2
- data/hobo_files/plugin/lib/hobo/rapid_helper.rb +1 -0
- data/hobo_files/plugin/lib/hobo/scopes.rb +15 -0
- data/hobo_files/plugin/lib/hobo/scopes/apply_scopes.rb +23 -0
- data/hobo_files/plugin/lib/hobo/scopes/association_proxy_extensions.rb +4 -2
- data/hobo_files/plugin/lib/hobo/scopes/automatic_scopes.rb +34 -7
- data/hobo_files/plugin/lib/hobo/scopes/defined_scope_proxy_extender.rb +3 -1
- data/hobo_files/plugin/lib/hobo/scopes/scoped_proxy.rb +1 -5
- data/hobo_files/plugin/taglibs/rapid.dryml +33 -24
- data/hobo_files/plugin/taglibs/rapid_editing.dryml +6 -5
- data/hobo_files/plugin/taglibs/rapid_forms.dryml +37 -31
- data/hobo_files/plugin/taglibs/rapid_generics.dryml +68 -27
- data/hobo_files/plugin/taglibs/rapid_navigation.dryml +5 -8
- data/hobo_files/plugin/taglibs/rapid_pages.dryml +71 -47
- data/hobo_files/plugin/taglibs/rapid_plus.dryml +4 -5
- data/hobo_files/plugin/taglibs/rapid_support.dryml +11 -4
- metadata +23 -6
- data/hobo_files/plugin/lib/rexml.rb +0 -443
@@ -130,6 +130,8 @@ module Hobo
|
|
130
130
|
empty = true
|
131
131
|
if this.respond_to?(:each_index)
|
132
132
|
this.each_index {|i| empty = false; new_field_context(i) { res << yield } }
|
133
|
+
elsif this.is_a?(Hash)
|
134
|
+
this.map {|key, value| empty = false; self.this_key = key; new_object_context(value) { res << yield } }
|
133
135
|
else
|
134
136
|
this.map {|e| empty = false; new_object_context(e) { res << yield } }
|
135
137
|
end
|
@@ -346,7 +348,7 @@ module Hobo
|
|
346
348
|
|
347
349
|
Hobo::ModelRouter.linkable?(klass, action, options.reverse_merge(:subsite => subsite))
|
348
350
|
end
|
349
|
-
|
351
|
+
|
350
352
|
|
351
353
|
# Convenience helper for the default app
|
352
354
|
|
@@ -26,11 +26,13 @@ module Hobo
|
|
26
26
|
|
27
27
|
class << base
|
28
28
|
alias_method_chain :has_many, :defined_scopes
|
29
|
+
alias_method_chain :has_many, :join_record_management
|
29
30
|
alias_method_chain :belongs_to, :creator_metadata
|
30
31
|
|
31
32
|
alias_method_chain :has_one, :new_method
|
32
33
|
|
33
34
|
def inherited(klass)
|
35
|
+
super
|
34
36
|
fields do
|
35
37
|
Hobo.register_model(klass)
|
36
38
|
field(klass.inheritance_column, :string)
|
@@ -92,7 +94,7 @@ module Hobo
|
|
92
94
|
|
93
95
|
def user_find(user, *args)
|
94
96
|
record = find(*args)
|
95
|
-
raise PermissionDeniedError unless Hobo.can_view?(user,
|
97
|
+
raise PermissionDeniedError unless Hobo.can_view?(user, record)
|
96
98
|
record
|
97
99
|
end
|
98
100
|
|
@@ -121,6 +123,11 @@ module Hobo
|
|
121
123
|
end
|
122
124
|
|
123
125
|
|
126
|
+
def user_update(user, id, attributes={})
|
127
|
+
find(id).user_save_changes(user, attributes)
|
128
|
+
end
|
129
|
+
|
130
|
+
|
124
131
|
def name_attribute
|
125
132
|
@name_attribute ||= begin
|
126
133
|
cols = columns.*.name
|
@@ -232,7 +239,7 @@ module Hobo
|
|
232
239
|
# FIXME: This should really be a method on AssociationReflection
|
233
240
|
def reverse_reflection(association_name)
|
234
241
|
refl = reflections[association_name]
|
235
|
-
return nil if refl.options[:conditions]
|
242
|
+
return nil if refl.options[:conditions] || refl.options[:polymorphic]
|
236
243
|
|
237
244
|
reverse_macro = if refl.macro == :has_many
|
238
245
|
:belongs_to
|
@@ -277,9 +284,36 @@ module Hobo
|
|
277
284
|
"#{name.underscore.pluralize}"
|
278
285
|
end
|
279
286
|
|
287
|
+
|
280
288
|
def typed_id
|
281
289
|
HoboFields.to_name(self) || name.underscore.gsub("/", "__")
|
282
290
|
end
|
291
|
+
|
292
|
+
|
293
|
+
def manage_join_records(association)
|
294
|
+
through = reflections[association].through_reflection
|
295
|
+
source = reflections[association].source_reflection
|
296
|
+
|
297
|
+
method = "manage_join_records_for_#{association}"
|
298
|
+
after_save method
|
299
|
+
class_eval %{
|
300
|
+
def #{method}
|
301
|
+
current = #{through.name}.*.#{source.name}
|
302
|
+
to_delete = current - #{association}
|
303
|
+
to_add = #{association} - current
|
304
|
+
#{through.klass.name}.delete_all(["#{through.primary_key_name} = ? and #{source.primary_key_name} in (?)",
|
305
|
+
self.id, to_delete.*.id]) if to_delete.any?
|
306
|
+
to_add.each { |record| #{association} << record }
|
307
|
+
end
|
308
|
+
}
|
309
|
+
end
|
310
|
+
|
311
|
+
def has_many_with_join_record_management(name, options={}, &b)
|
312
|
+
manage = options.delete(:managed)
|
313
|
+
returning (has_many_without_join_record_management(name, options, &b)) do
|
314
|
+
manage_join_records(name) if manage
|
315
|
+
end
|
316
|
+
end
|
283
317
|
|
284
318
|
end # --- of ClassMethods --- #
|
285
319
|
|
@@ -441,16 +475,12 @@ module Hobo
|
|
441
475
|
|
442
476
|
|
443
477
|
def convert_type_for_mass_assignment(field_type, value)
|
444
|
-
if field_type.is_a?(ActiveRecord::Reflection::AssociationReflection)
|
445
|
-
|
446
|
-
|
447
|
-
# TODO: This @foo_1 feature is rarely (never?) used - get rid of it
|
448
|
-
Hobo.object_from_dom_id(value[1..-1])
|
449
|
-
else
|
450
|
-
value
|
451
|
-
end
|
478
|
+
if field_type.is_a?(ActiveRecord::Reflection::AssociationReflection)
|
479
|
+
convert_associated_records_for_mass_assignment(field_type, value)
|
480
|
+
|
452
481
|
elsif !field_type.is_a?(Class)
|
453
482
|
value
|
483
|
+
|
454
484
|
elsif field_type <= Date
|
455
485
|
if value.is_a? Hash
|
456
486
|
Date.new(*(%w{year month day}.map{|s| value[s].to_i}))
|
@@ -460,6 +490,7 @@ module Hobo
|
|
460
490
|
else
|
461
491
|
value
|
462
492
|
end
|
493
|
+
|
463
494
|
elsif field_type <= Time
|
464
495
|
if value.is_a? Hash
|
465
496
|
Time.local(*(%w{year month day hour minute}.map{|s| value[s].to_i}))
|
@@ -468,13 +499,42 @@ module Hobo
|
|
468
499
|
else
|
469
500
|
value
|
470
501
|
end
|
502
|
+
|
471
503
|
elsif field_type <= Hobo::Boolean
|
472
504
|
(value.is_a?(String) && value.strip.downcase.in?(['0', 'false']) || value.blank?) ? false : true
|
505
|
+
|
473
506
|
else
|
474
507
|
# primitive field
|
475
508
|
value
|
476
509
|
end
|
477
510
|
end
|
511
|
+
|
512
|
+
def convert_associated_records_for_mass_assignment(reflection, value)
|
513
|
+
if reflection.macro.in?([:belongs_to, :has_one])
|
514
|
+
if value.is_a?(String) && value.starts_with?('@')
|
515
|
+
# TODO: This @foo_1 feature is rarely (never?) used - get rid of it
|
516
|
+
Hobo.object_from_dom_id(value[1..-1])
|
517
|
+
else
|
518
|
+
value
|
519
|
+
end
|
520
|
+
elsif reflection.macro == :has_many
|
521
|
+
if reflection.klass.try.name_attribute
|
522
|
+
value.map do |x|
|
523
|
+
if x.is_a?(String)
|
524
|
+
reflection.klass[x] unless x.blank?
|
525
|
+
else
|
526
|
+
x
|
527
|
+
end
|
528
|
+
end.compact
|
529
|
+
else
|
530
|
+
value
|
531
|
+
end
|
532
|
+
|
533
|
+
else
|
534
|
+
# unknown kind of accociation - no conversion
|
535
|
+
value
|
536
|
+
end
|
537
|
+
end
|
478
538
|
|
479
539
|
end
|
480
540
|
|
@@ -138,9 +138,11 @@ module Hobo
|
|
138
138
|
def destroy; hobo_destroy end if include_action?(:destroy)
|
139
139
|
|
140
140
|
def completions; hobo_completions end if include_action?(:completions)
|
141
|
+
|
142
|
+
def reorder; hobo_reorder end if include_action?(:reorder)
|
141
143
|
end
|
142
144
|
|
143
|
-
collections.each { |c| def_collection_actions(c.to_sym) }
|
145
|
+
collections.each { |c| def_collection_actions(c.to_sym) }
|
144
146
|
end
|
145
147
|
|
146
148
|
|
@@ -205,7 +207,10 @@ module Hobo
|
|
205
207
|
|
206
208
|
|
207
209
|
def available_auto_actions
|
208
|
-
|
210
|
+
(available_auto_read_actions +
|
211
|
+
available_auto_write_actions +
|
212
|
+
FORM_ACTIONS +
|
213
|
+
available_auto_collection_actions).uniq
|
209
214
|
end
|
210
215
|
|
211
216
|
|
@@ -215,7 +220,11 @@ module Hobo
|
|
215
220
|
|
216
221
|
|
217
222
|
def available_auto_write_actions
|
218
|
-
|
223
|
+
if "position_column".in?(model.instance_methods)
|
224
|
+
WRITE_ONLY_ACTIONS + [:reorder]
|
225
|
+
else
|
226
|
+
WRITE_ONLY_ACTIONS
|
227
|
+
end
|
219
228
|
end
|
220
229
|
|
221
230
|
|
@@ -229,38 +238,17 @@ module Hobo
|
|
229
238
|
protected
|
230
239
|
|
231
240
|
|
232
|
-
def
|
233
|
-
filters = args.extract_options!
|
234
|
-
finder = args.first || self.model
|
235
|
-
|
236
|
-
filters.each_pair do |scope, arg|
|
237
|
-
dont_filter = arg.is_a?(Array) ? arg.compact.empty? : arg.nil?
|
238
|
-
finder = finder.send(scope, arg) unless dont_filter
|
239
|
-
end
|
240
|
-
finder
|
241
|
-
end
|
242
|
-
|
243
|
-
|
244
|
-
def sort_fields(*args)
|
245
|
-
finder = args.first.is_a?(Class) ? args.shift : model
|
246
|
-
|
241
|
+
def parse_sort_param(*sort_fields)
|
247
242
|
_, desc, field = *params[:sort]._?.match(/^(-)?([a-z_]+(?:\.[a-z_]+)?)$/)
|
248
243
|
|
249
244
|
if field
|
250
|
-
|
251
|
-
if field.in?(fields)
|
245
|
+
if field.in?(sort_fields.*.to_s)
|
252
246
|
@sort_field = field
|
253
247
|
@sort_direction = desc ? "desc" : "asc"
|
254
248
|
|
255
|
-
|
256
|
-
[$1.camelize.constantize.table_name, $2]
|
257
|
-
else
|
258
|
-
[finder.table_name, field]
|
259
|
-
end
|
260
|
-
finder = finder.order("#{table}.#{column}", @sort_direction)
|
249
|
+
[@sort_field, @sort_direction]
|
261
250
|
end
|
262
251
|
end
|
263
|
-
finder
|
264
252
|
end
|
265
253
|
|
266
254
|
|
@@ -301,7 +289,7 @@ module Hobo
|
|
301
289
|
object_url(@this) ||
|
302
290
|
|
303
291
|
# Then the show page of the 'owning' object if there is one
|
304
|
-
(@this.class.default_dependent_on && object_url(@this.class.default_dependent_on)) ||
|
292
|
+
(@this.class.default_dependent_on && object_url(@this.send(@this.class.default_dependent_on))) ||
|
305
293
|
|
306
294
|
# Last try - the index page for this model
|
307
295
|
object_url(@this.class) ||
|
@@ -322,8 +310,18 @@ module Hobo
|
|
322
310
|
end
|
323
311
|
end
|
324
312
|
|
313
|
+
|
314
|
+
def request_requires_pagination?
|
315
|
+
# Internet explorer has a penchant for saying it would mostly
|
316
|
+
# like an image, if you clicked on an image link
|
317
|
+
request.format.in?(PAGINATE_FORMATS) || request.format.to_s =~ %r(image/)
|
318
|
+
end
|
319
|
+
|
320
|
+
|
325
321
|
def find_or_paginate(finder, options)
|
326
|
-
|
322
|
+
options = options.reverse_merge(:paginate => request_requires_pagination?)
|
323
|
+
do_pagination = options.delete(:paginate)
|
324
|
+
|
327
325
|
if do_pagination && !finder.respond_to?(:paginate)
|
328
326
|
do_pagination = false
|
329
327
|
logger.warn "Hobo::ModelController: Pagination is not available. To enable, please install will_paginate or a duck-type compatible paginator"
|
@@ -419,7 +417,7 @@ module Hobo
|
|
419
417
|
|
420
418
|
|
421
419
|
def update_response(in_place_edit_field=nil, &b)
|
422
|
-
flash[:notice] = "Changes to the #{@this.class.name.
|
420
|
+
flash[:notice] = "Changes to the #{@this.class.name.titleize.downcase} were saved" if !request.xhr? && valid?
|
423
421
|
|
424
422
|
response_block(&b) or
|
425
423
|
if valid?
|
@@ -464,7 +462,7 @@ module Hobo
|
|
464
462
|
response_block(&b) or
|
465
463
|
respond_to do |wants|
|
466
464
|
wants.html { redirect_to(:action => "index") }
|
467
|
-
wants.js { hobo_ajax_response || render(:
|
465
|
+
wants.js { hobo_ajax_response || render(:nothing => true) }
|
468
466
|
end
|
469
467
|
end
|
470
468
|
|
@@ -498,6 +496,14 @@ module Hobo
|
|
498
496
|
end
|
499
497
|
|
500
498
|
|
499
|
+
def hobo_reorder
|
500
|
+
params["#{model.name.underscore}_ordering"].each_with_index do |id, position|
|
501
|
+
model.user_update(current_user, id, :position => position+1)
|
502
|
+
end
|
503
|
+
hobo_ajax_response || render(:nothing => true)
|
504
|
+
end
|
505
|
+
|
506
|
+
|
501
507
|
|
502
508
|
# --- Response helpers --- #
|
503
509
|
|
@@ -505,10 +511,19 @@ module Hobo
|
|
505
511
|
def permission_denied(error)
|
506
512
|
if respond_to? :permission_denied_response
|
507
513
|
permission_denied_response
|
508
|
-
elsif render_tag("permission-denied-page", { }, :status => 403)
|
509
|
-
# job done
|
510
514
|
else
|
511
|
-
|
515
|
+
respond_to do |wants|
|
516
|
+
wants.html do
|
517
|
+
if render_tag("permission-denied-page", { }, :status => 403)
|
518
|
+
# job done
|
519
|
+
else
|
520
|
+
render :text => "Permission Denied", :status => 403
|
521
|
+
end
|
522
|
+
end
|
523
|
+
wants.js do
|
524
|
+
render :text => "Permission Denied", :status => 403
|
525
|
+
end
|
526
|
+
end
|
512
527
|
end
|
513
528
|
end
|
514
529
|
|
@@ -10,8 +10,10 @@ class ActionController::Routing::RouteSet
|
|
10
10
|
|
11
11
|
# temporay hack -- reload assemble.rb whenever routes need reloading
|
12
12
|
def reload_with_hobo_assemble
|
13
|
-
|
14
|
-
|
13
|
+
if defined? ::ApplicationController
|
14
|
+
load "#{RAILS_ROOT}/app/assemble.rb" if File.exists? "#{RAILS_ROOT}/app/assemble.rb"
|
15
|
+
reload_without_hobo_assemble
|
16
|
+
end
|
15
17
|
end
|
16
18
|
alias_method_chain :reload, :hobo_assemble
|
17
19
|
|
@@ -131,6 +133,7 @@ module Hobo
|
|
131
133
|
collection_routes
|
132
134
|
web_method_routes
|
133
135
|
show_action_routes
|
136
|
+
reorder_route
|
134
137
|
user_routes if controller < Hobo::UserController
|
135
138
|
end
|
136
139
|
end
|
@@ -192,6 +195,11 @@ module Hobo
|
|
192
195
|
end
|
193
196
|
end
|
194
197
|
|
198
|
+
|
199
|
+
def reorder_route
|
200
|
+
linkable_route("reorder_#{plural}", "#{plural}/reorder", 'reorder', :conditions => { :method => :post })
|
201
|
+
end
|
202
|
+
|
195
203
|
|
196
204
|
def user_routes
|
197
205
|
prefix = plural == "users" ? "" : "#{singular}_"
|
@@ -13,6 +13,8 @@ module Hobo
|
|
13
13
|
module ClassMethods
|
14
14
|
|
15
15
|
include AutomaticScopes
|
16
|
+
|
17
|
+
include ApplyScopes
|
16
18
|
|
17
19
|
def defined_scopes
|
18
20
|
@defined_scopes
|
@@ -29,6 +31,19 @@ module Hobo
|
|
29
31
|
end
|
30
32
|
|
31
33
|
|
34
|
+
def apply_scopes(scopes)
|
35
|
+
result = self
|
36
|
+
scopes.each_pair do |scope, arg|
|
37
|
+
if arg.is_a?(Array)
|
38
|
+
result = result.send(scope, *arg) unless arg.first.blank?
|
39
|
+
else
|
40
|
+
result = result.send(scope, arg) unless arg.blank?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
result
|
44
|
+
end
|
45
|
+
|
46
|
+
|
32
47
|
def alias_scope(new_name, old_name)
|
33
48
|
metaclass.send(:alias_method, new_name, old_name)
|
34
49
|
defined_scopes[new_name] = defined_scopes[old_name]
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Hobo
|
2
|
+
|
3
|
+
module Scopes
|
4
|
+
|
5
|
+
module ApplyScopes
|
6
|
+
|
7
|
+
def apply_scopes(scopes)
|
8
|
+
result = self
|
9
|
+
scopes.each_pair do |scope, arg|
|
10
|
+
if arg.is_a?(Array)
|
11
|
+
result = result.send(scope, *arg) unless arg.first.blank?
|
12
|
+
else
|
13
|
+
result = result.send(scope, arg) unless arg.blank?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
result
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -18,9 +18,11 @@ module Hobo
|
|
18
18
|
target_class.send(scope_name).scope(:find)[:conditions]
|
19
19
|
end
|
20
20
|
if scope_conditions && conditions_without_hobo_scopes
|
21
|
-
"#{conditions_without_hobo_scopes} AND #{scope_conditions}"
|
21
|
+
"(#{sanitize_sql conditions_without_hobo_scopes}) AND (#{sanitize_sql scope_conditions})"
|
22
|
+
elsif scope_conditions
|
23
|
+
sanitize_sql scope_conditions
|
22
24
|
else
|
23
|
-
|
25
|
+
conditions_without_hobo_scopes
|
24
26
|
end
|
25
27
|
end
|
26
28
|
|
@@ -152,17 +152,17 @@ module Hobo
|
|
152
152
|
end
|
153
153
|
|
154
154
|
# published
|
155
|
-
elsif (col = column(
|
155
|
+
elsif (col = column(name)) && (col.type == :boolean)
|
156
156
|
|
157
157
|
def_scope do
|
158
|
-
{ :conditions => "#{column_sql(col)}
|
158
|
+
{ :conditions => "#{column_sql(col)}" }
|
159
159
|
end
|
160
160
|
|
161
161
|
# not_published
|
162
|
-
elsif (col = column($1)) && (col.type == :boolean)
|
162
|
+
elsif name =~ /^not_(.*)$/ && (col = column($1)) && (col.type == :boolean)
|
163
163
|
|
164
164
|
def_scope do
|
165
|
-
{ :conditions => "#{column_sql(col)}
|
165
|
+
{ :conditions => "NOT #{column_sql(col)}" }
|
166
166
|
end
|
167
167
|
|
168
168
|
# published_before(time)
|
@@ -200,11 +200,38 @@ module Hobo
|
|
200
200
|
def_scope do |count|
|
201
201
|
{ :limit => count }
|
202
202
|
end
|
203
|
-
|
203
|
+
|
204
204
|
when "order_by"
|
205
|
+
klass = @klass
|
205
206
|
def_scope do |*args|
|
206
207
|
field, asc = args
|
207
|
-
|
208
|
+
type = klass.attr_type(field)
|
209
|
+
if type.respond_to?(:table_name) && (name = type.name_attribute)
|
210
|
+
include = field
|
211
|
+
colspec = "#{type.table_name}.#{name}"
|
212
|
+
else
|
213
|
+
colspec = "#{klass.table_name}.#{field}"
|
214
|
+
end
|
215
|
+
{ :order => "#{colspec} #{asc._?.upcase}", :include => include }
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
when "include"
|
220
|
+
def_scope do |inclusions|
|
221
|
+
{ :include => inclusions }
|
222
|
+
end
|
223
|
+
|
224
|
+
when "search"
|
225
|
+
def_scope do |query, *fields|
|
226
|
+
words = query.split
|
227
|
+
args = []
|
228
|
+
word_queries = words.map do |word|
|
229
|
+
field_query = '(' + fields.map { |field| "(#{@klass.table_name}.#{field} like ?)" }.join(" OR ") + ')'
|
230
|
+
args += ["%#{word}%"] * fields.length
|
231
|
+
field_query
|
232
|
+
end
|
233
|
+
|
234
|
+
{ :conditions => [word_queries.join(" OR ")] + args }
|
208
235
|
end
|
209
236
|
|
210
237
|
else
|
@@ -236,7 +263,7 @@ module Hobo
|
|
236
263
|
|
237
264
|
"EXISTS (SELECT * FROM #{related.table_name} " +
|
238
265
|
"WHERE #{related.table_name}.#{foreign_key} = #{owner_primary_key} AND " +
|
239
|
-
"#{related.table_name}.#{related.primary_key} = ?"
|
266
|
+
"#{related.table_name}.#{related.primary_key} = ?)"
|
240
267
|
end
|
241
268
|
end
|
242
269
|
|