fake_arel 0.2 → 0.5

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/lib/fake_arel.rb CHANGED
@@ -8,7 +8,7 @@ require 'fake_arel/with_scope_replacement'
8
8
  require 'fake_arel/rails_3_finders'
9
9
 
10
10
  module FakeArel
11
- VERSION = '0.2'
11
+ VERSION = '0.5'
12
12
  ActiveRecord::Base.send :include, Rails3Finders
13
13
  ActiveRecord::Base.send :include, WithScopeReplacement
14
14
  end
@@ -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
- if self.model_name != parent_scope.model_name
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
- options = options.proxy_options if options.class == ActiveRecord::NamedScope::Scope
52
- [options[:extend]].flatten.each { |extension| extend extension } if options[:extend]
53
- extend Module.new(&block) if block_given?
54
- unless Scope === proxy_scope
55
- @current_scoped_methods_when_defined = proxy_scope.send(:current_scoped_methods)
56
- end
57
- @proxy_scope, @proxy_options = proxy_scope, options.except(:extend)
58
- end
59
-
60
- def reload
61
- load_found; self
62
- end
63
-
64
- def first(*args)
65
- if args.first.kind_of?(Integer) || (@found && !args.first.kind_of?(Hash))
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 {|order| {:order => order }}
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
@@ -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
@@ -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: 15
4
+ hash: 1
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 2
9
- version: "0.2"
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-13 00:00:00 -04:00
17
+ date: 2010-08-17 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency