2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
# File 'lib/fake_arel/with_scope_replacement.rb', line 2
def self.included(base)
base.class_eval do
class << self
def to_sql
options = current_scoped_methods
join_dependency = JoinDependency.new(self, merge_includes(scope(:find, :include), nil), nil)
scope = scope(:find)
sql = "SELECT #{(scope && scope[:select]) || default_select(options[:joins] || (scope && scope[:joins]))} "
sql << "FROM #{(scope && scope[:from]) || quoted_table_name} "
sql << join_dependency.join_associations.collect{|join| join.association_join }.join
add_joins!(sql, options[:joins], scope)
add_conditions!(sql, options[:conditions], scope)
add_limited_ids_condition!(sql, options, join_dependency) if !using_limitable_reflections?(join_dependency.reflections) && ((scope && scope[:limit]) || options[:limit])
add_group!(sql, options[:group], options[:having], scope)
add_order!(sql, options[:order], scope)
add_limit!(sql, options, scope) if using_limitable_reflections?(join_dependency.reflections)
add_lock!(sql, options, scope)
return sanitize_sql(sql)
end
def with_scope(method_scoping = {}, action = :merge, &block)
method_scoping = {:find => method_scoping.proxy_options} if method_scoping.class == ActiveRecord::NamedScope::Scope
method_scoping = method_scoping.method_scoping if method_scoping.respond_to?(:method_scoping)
method_scoping = method_scoping.inject({}) do |hash, (method, params)|
hash[method] = (params == true) ? params : params.dup
hash
end
method_scoping.assert_valid_keys([ :find, :create ])
if f = method_scoping[:find]
f.assert_valid_keys(VALID_FIND_OPTIONS)
set_readonly_option! f
end
if [:merge, :reverse_merge].include?(action) && current_scoped_methods
method_scoping = current_scoped_methods.inject(method_scoping) do |hash, (method, params)|
case hash[method]
when Hash
if method == :find
(hash[method].keys + params.keys).uniq.each do |key|
merge = hash[method][key] && params[key] if key == :conditions && merge
if params[key].is_a?(Hash) && hash[method][key].is_a?(Hash)
hash[method][key] = merge_conditions(hash[method][key].deep_merge(params[key]))
else
hash[method][key] = merge_conditions(params[key], hash[method][key])
end
elsif key == :select && merge
hash[method][key] = merge_includes(hash[method][key], params[key]).uniq.join(', ')
elsif key == :readonly
hash[method][key] = params[key] unless params[:readonly].nil?
elsif key == :include && merge
hash[method][key] = merge_includes(hash[method][key], params[key]).uniq
elsif key == :joins && merge
hash[method][key] = merge_joins(params[key], hash[method][key])
elsif [:group, :order].include?(key) && merge && !default_scoping.any?{ |s| s[method].keys.include?(key) }
hash[method][key] = [hash[method][key], params[key]].select{|o| !o.blank?}.join(', ')
else
hash[method][key] = hash[method][key] || params[key]
end
end
else
if action == :reverse_merge
hash[method] = hash[method].merge(params)
else
hash[method] = params.merge(hash[method])
end
end
else
hash[method] = params
end
hash
end
end
self.scoped_methods << method_scoping
begin
yield
ensure
self.scoped_methods.pop
end
end
end
end
end
|