fake_arel 0.2 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/fake_arel.rb +1 -1
- data/lib/fake_arel/extensions.rb +19 -101
- data/lib/fake_arel/rails_3_finders.rb +2 -2
- data/lib/fake_arel/with_scope_replacement.rb +5 -7
- data/spec/fake_arel_spec.rb +26 -1
- data/spec/fixtures/reply.rb +7 -0
- data/spec/test.db +0 -0
- metadata +4 -4
data/lib/fake_arel.rb
CHANGED
data/lib/fake_arel/extensions.rb
CHANGED
@@ -6,26 +6,10 @@ module ActiveRecord
|
|
6
6
|
|
7
7
|
scopes[name] = lambda do |parent_scope, *args|
|
8
8
|
Scope.new(parent_scope, case options
|
9
|
-
when Hash
|
9
|
+
when Hash, Scope
|
10
10
|
options
|
11
|
-
when Scope
|
12
|
-
# unspin the scope and generate a hash
|
13
|
-
local_scope = options.proxy_scope
|
14
|
-
ret = options.proxy_options
|
15
|
-
while local_scope.class == ActiveRecord::NamedScope::Scope
|
16
|
-
ret[:conditions] = merge_conditions(ret[:conditions], local_scope.proxy_options[:conditions])
|
17
|
-
ret[:includes] = merge_includes(ret[:includes], local_scope.proxy_options[:includes]) if ret[:includes] || local_scope.proxy_options[:includes]
|
18
|
-
ret[:joins] = merge_includes(ret[:joins], local_scope.proxy_options[:joins])
|
19
|
-
ret[:order] = merge_includes(ret[:order], local_scope.proxy_options[:order]) if ret[:order] || local_scope.proxy_options[:order]
|
20
|
-
local_scope = local_scope.proxy_scope
|
21
|
-
end
|
22
|
-
ret
|
23
11
|
when Proc
|
24
|
-
|
25
|
-
options.bind(parent_scope).call(*args)
|
26
|
-
else
|
27
|
-
options.call(*args)
|
28
|
-
end
|
12
|
+
options.call(*args)
|
29
13
|
end, &block)
|
30
14
|
end
|
31
15
|
|
@@ -36,92 +20,26 @@ module ActiveRecord
|
|
36
20
|
end
|
37
21
|
|
38
22
|
class Scope
|
39
|
-
attr_reader :proxy_scope, :proxy_options, :current_scoped_methods_when_defined
|
40
23
|
undef select
|
41
|
-
[].methods.each do |m|
|
42
|
-
unless m =~ /^__/ || (NON_DELEGATE_METHODS + ['select']).include?(m.to_s)
|
43
|
-
delegate m, :to => :proxy_found
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
delegate :scopes, :with_scope, :scoped_methods, :to => :proxy_scope
|
48
24
|
|
25
|
+
alias initialize_without_arel initialize
|
49
26
|
def initialize(proxy_scope, options = {}, &block)
|
50
|
-
options
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
proxy_found.first(*args)
|
67
|
-
else
|
68
|
-
find(:first, *args)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def last(*args)
|
73
|
-
if args.first.kind_of?(Integer) || (@found && !args.first.kind_of?(Hash))
|
74
|
-
proxy_found.last(*args)
|
75
|
-
else
|
76
|
-
find(:last, *args)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def size
|
81
|
-
@found ? @found.length : count
|
82
|
-
end
|
83
|
-
|
84
|
-
def empty?
|
85
|
-
@found ? @found.empty? : count.zero?
|
86
|
-
end
|
87
|
-
|
88
|
-
def respond_to?(method, include_private = false)
|
89
|
-
super || @proxy_scope.respond_to?(method, include_private)
|
90
|
-
end
|
91
|
-
|
92
|
-
def any?
|
93
|
-
if block_given?
|
94
|
-
proxy_found.any? { |*block_args| yield(*block_args) }
|
95
|
-
else
|
96
|
-
!empty?
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
protected
|
101
|
-
def proxy_found
|
102
|
-
@found || load_found
|
103
|
-
end
|
104
|
-
|
105
|
-
private
|
106
|
-
def method_missing(method, *args, &block)
|
107
|
-
if scopes.include?(method)
|
108
|
-
scopes[method].call(self, *args)
|
109
|
-
else
|
110
|
-
with_scope({:find => proxy_options, :create => proxy_options[:conditions].is_a?(Hash) ? proxy_options[:conditions] : {}}, :reverse_merge) do
|
111
|
-
method = :new if method == :build
|
112
|
-
if current_scoped_methods_when_defined && !scoped_methods.include?(current_scoped_methods_when_defined)
|
113
|
-
with_scope current_scoped_methods_when_defined do
|
114
|
-
proxy_scope.send(method, *args, &block)
|
115
|
-
end
|
116
|
-
else
|
117
|
-
proxy_scope.send(method, *args, &block)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
def load_found
|
124
|
-
@found = find(:all)
|
27
|
+
options = options.unspin if options.class == ActiveRecord::NamedScope::Scope
|
28
|
+
initialize_without_arel(proxy_scope, options, &block)
|
29
|
+
end
|
30
|
+
|
31
|
+
def unspin
|
32
|
+
# unspin the scope and generate a hash
|
33
|
+
local_scope = proxy_scope
|
34
|
+
ret = proxy_options
|
35
|
+
while local_scope.class == ActiveRecord::NamedScope::Scope
|
36
|
+
ret[:conditions] = merge_conditions(ret[:conditions], local_scope.proxy_options[:conditions])
|
37
|
+
ret[:includes] = merge_includes(ret[:includes], local_scope.proxy_options[:includes]) if ret[:includes] || local_scope.proxy_options[:includes]
|
38
|
+
ret[:joins] = merge_includes(ret[:joins], local_scope.proxy_options[:joins])
|
39
|
+
ret[:order] = [local_scope.proxy_options[:order], ret[:order]].select{|o| !o.blank?}.join(',') if ret[:order] || local_scope.proxy_options[:order]
|
40
|
+
local_scope = local_scope.proxy_scope
|
41
|
+
end
|
42
|
+
ret
|
125
43
|
end
|
126
44
|
end
|
127
45
|
|
@@ -7,8 +7,8 @@ module Rails3Finders
|
|
7
7
|
named_scope :offset, lambda {|offset| {:offset => offset}}
|
8
8
|
named_scope :limit, lambda {|limit| {:limit => limit}}
|
9
9
|
named_scope :includes, lambda { |*includes| { :include => includes }}
|
10
|
-
named_scope :select, lambda {|*select| {:select => select }}
|
11
|
-
named_scope :order, lambda {
|
10
|
+
named_scope :select, lambda {|*select| {:select => select.join(',') }}
|
11
|
+
named_scope :order, lambda {|*order| {:order => order.join(',') }}
|
12
12
|
named_scope :joins, lambda {|*join| {:joins => join }}
|
13
13
|
named_scope :from, lambda {|*from| {:from => from }}
|
14
14
|
named_scope :having, lambda {|*having| {:having => having }}
|
@@ -5,7 +5,7 @@ module WithScopeReplacement
|
|
5
5
|
def to_sql
|
6
6
|
construct_finder_sql self.current_scoped_methods[:find]
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
def with_scope(method_scoping = {}, action = :merge, &block)
|
10
10
|
method_scoping = {:find => method_scoping.proxy_options} if method_scoping.class == ActiveRecord::NamedScope::Scope
|
11
11
|
method_scoping = method_scoping.method_scoping if method_scoping.respond_to?(:method_scoping)
|
@@ -41,6 +41,10 @@ module WithScopeReplacement
|
|
41
41
|
hash[method][key] = merge_includes(hash[method][key], params[key]).uniq
|
42
42
|
elsif key == :joins && merge
|
43
43
|
hash[method][key] = merge_joins(params[key], hash[method][key])
|
44
|
+
# see https://rails.lighthouseapp.com/projects/8994/tickets/2810-with_scope-should-accept-and-use-order-option
|
45
|
+
# it works now in reverse order to comply with ActiveRecord 3
|
46
|
+
elsif key == :order && merge && !default_scoping.any?{ |s| s[method].keys.include?(key) }
|
47
|
+
hash[method][key] = [hash[method][key], params[key]].select{|o| !o.blank?}.join(', ')
|
44
48
|
else
|
45
49
|
hash[method][key] = hash[method][key] || params[key]
|
46
50
|
end
|
@@ -66,12 +70,6 @@ module WithScopeReplacement
|
|
66
70
|
self.scoped_methods.pop
|
67
71
|
end
|
68
72
|
end
|
69
|
-
|
70
|
-
# Works like with_scope, but discards any nested properties.
|
71
|
-
def with_exclusive_scope(method_scoping = {}, &block)
|
72
|
-
with_scope(method_scoping, :overwrite, &block)
|
73
|
-
end
|
74
|
-
|
75
73
|
end
|
76
74
|
end
|
77
75
|
end
|
data/spec/fake_arel_spec.rb
CHANGED
@@ -67,10 +67,35 @@ describe "chained nested named scopes" do
|
|
67
67
|
Reply.topic_4_id_asc.all.should == Reply.find(:all, :conditions => {:topic_id => 4}, :order=>'id asc')
|
68
68
|
Reply.topic_4_id_desc.all.should == Reply.find(:all, :conditions => {:topic_id => 4}, :order=>'id desc')
|
69
69
|
end
|
70
|
+
|
71
|
+
it "should properly chain scope in definitions by lambda" do
|
72
|
+
Reply.recent_topic_id(4).all.should == Reply.find_all_by_id(5)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should properly chain order scope in definitions by lambda" do
|
76
|
+
Reply.topic__id_asc(4).all.should == Reply.find(:all, :conditions => {:topic_id => 4}, :order=>'id asc')
|
77
|
+
Reply.order('id desc').topic_id(4).all.should == Reply.find(:all, :conditions => {:topic_id => 4}, :order=>'id desc')
|
78
|
+
Reply.topic__id_desc(4).all.should == Reply.find(:all, :conditions => {:topic_id => 4}, :order=>'id desc')
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should chain order scopes" do
|
82
|
+
# see https://rails.lighthouseapp.com/projects/8994/tickets/2810-with_scope-should-accept-and-use-order-option
|
83
|
+
# it works now in reverse order to comply with ActiveRecord 3
|
84
|
+
Reply.order('topic_id asc').order('created_at desc').all.should == Reply.find(:all, :order=>'topic_id asc, created_at desc')
|
85
|
+
Reply.order('topic_id asc').id_desc.all.should == Reply.find(:all, :order=>'topic_id asc, id desc')
|
86
|
+
Reply.topic_id_asc.id_desc.all.should == Reply.find(:all, :order=>'topic_id asc, id desc')
|
87
|
+
Reply.topic_id_asc_id_desc.all.should == Reply.find(:all, :order=>'topic_id asc, id desc')
|
88
|
+
Reply.lam_topic_id_asc_id_desc.all.should == Reply.find(:all, :order=>'topic_id asc, id desc')
|
89
|
+
Reply.with_scope(:find=>{:order=>'topic_id asc'}) do
|
90
|
+
Reply.with_scope(:find=>{:order=>'created_at desc'}) do
|
91
|
+
Reply.all
|
92
|
+
end
|
93
|
+
end.should == Reply.find(:all, :order=>'created_at desc, topic_id asc')
|
94
|
+
end
|
70
95
|
end
|
71
96
|
|
72
97
|
describe "keep scoped functionality" do
|
73
98
|
it "should respond to scoped" do
|
74
|
-
Reply.scoped.class.should == ActiveRecord::NamedScope::Scope
|
99
|
+
Reply.scoped({}).class.should == ActiveRecord::NamedScope::Scope
|
75
100
|
end
|
76
101
|
end
|
data/spec/fixtures/reply.rb
CHANGED
@@ -19,6 +19,13 @@ class Reply < ActiveRecord::Base
|
|
19
19
|
named_scope :id_desc, order('id desc')
|
20
20
|
named_scope :topic_4_id_asc, id_asc.where(:topic_id => 4)
|
21
21
|
named_scope :topic_4_id_desc, id_desc.where(:topic_id => 4)
|
22
|
+
named_scope :topic_id, lambda{|topic_id| where(:topic_id => topic_id)}
|
23
|
+
named_scope :recent_topic_id, lambda{|topic_id| recent.where(:topic_id => topic_id)}
|
24
|
+
named_scope :topic__id_asc, lambda{|topic_id| id_asc.where(:topic_id => topic_id)}
|
25
|
+
named_scope :topic__id_desc, lambda{|topic_id| id_desc.where(:topic_id => topic_id)}
|
26
|
+
named_scope :topic_id_asc, order('topic_id asc')
|
27
|
+
named_scope :topic_id_asc_id_desc, order('topic_id asc').id_desc
|
28
|
+
named_scope :lam_topic_id_asc_id_desc, lambda{ topic_id_asc.id_desc }
|
22
29
|
|
23
30
|
validates_presence_of :content
|
24
31
|
|
data/spec/test.db
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fake_arel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 1
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: "0.
|
8
|
+
- 5
|
9
|
+
version: "0.5"
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Grant Ammons
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-08-
|
17
|
+
date: 2010-08-17 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|