metaskills-grouped_scope 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +1 -1
- data/Rakefile +2 -2
- data/lib/grouped_scope.rb +2 -1
- data/lib/grouped_scope/core_ext.rb +13 -5
- data/lib/grouped_scope/has_many_association.rb +1 -3
- data/test/grouped_scope/association_reflection_test.rb +2 -10
- data/test/lib/boot.rb +0 -1
- metadata +2 -8
- data/test/lib/core_ext.rb +0 -20
- data/test/lib/named_scope.rb +0 -7
- data/test/lib/named_scope/core_ext.rb +0 -82
- data/test/lib/named_scope/named_scope.rb +0 -168
- data/test/lib/named_scope/named_scope_patch_1.2.rb +0 -85
- data/test/lib/named_scope/named_scope_patch_2.0.rb +0 -55
data/README.rdoc
CHANGED
@@ -5,7 +5,7 @@ GroupedScope aims to make two things easier in your ActiveRecord models. First,
|
|
5
5
|
easy way to group objects, second, to allow the group to share associated object via existing
|
6
6
|
has_many relationships. See installation and usage for more details.
|
7
7
|
|
8
|
-
By the way, this plugin has been tested with rails
|
8
|
+
By the way, this plugin has been tested with rails 2.3.2, 2.2.2, and 2.1.1
|
9
9
|
|
10
10
|
|
11
11
|
=== Installation & Usage
|
data/Rakefile
CHANGED
@@ -20,10 +20,10 @@ Rake::TestTask.new(:test) do |t|
|
|
20
20
|
t.verbose = true
|
21
21
|
end
|
22
22
|
|
23
|
-
desc 'Test the GroupedScope plugin with Rails 2.
|
23
|
+
desc 'Test the GroupedScope plugin with Rails 2.3.2, 2.2.2, and 2.1.1 gems'
|
24
24
|
task :test_rails do
|
25
25
|
test = Rake::Task['test']
|
26
|
-
versions = ['2.
|
26
|
+
versions = ['2.3.2','2.2.2','2.1.1']
|
27
27
|
versions.each do |version|
|
28
28
|
ENV['RAILS_VERSION'] = "#{version}"
|
29
29
|
test.invoke
|
data/lib/grouped_scope.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'active_record/version'
|
1
2
|
require 'grouped_scope/errors'
|
2
3
|
require 'grouped_scope/grouping'
|
3
4
|
require 'grouped_scope/self_grouping'
|
@@ -9,7 +10,7 @@ require 'grouped_scope/core_ext'
|
|
9
10
|
|
10
11
|
module GroupedScope
|
11
12
|
|
12
|
-
VERSION = '0.
|
13
|
+
VERSION = '0.6.0'
|
13
14
|
|
14
15
|
end
|
15
16
|
|
@@ -5,13 +5,21 @@ class ActiveRecord::Base
|
|
5
5
|
|
6
6
|
private
|
7
7
|
|
8
|
-
def attribute_condition_with_grouped_scope(
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
def attribute_condition_with_grouped_scope(*args)
|
9
|
+
if ActiveRecord::VERSION::STRING >= '2.3.0'
|
10
|
+
quoted_column_name, argument = args
|
11
|
+
case argument
|
12
|
+
when GroupedScope::SelfGroupping then "#{quoted_column_name} IN (?)"
|
13
|
+
else attribute_condition_without_grouped_scope(quoted_column_name,argument)
|
14
|
+
end
|
15
|
+
else
|
16
|
+
argument = args.first
|
17
|
+
case argument
|
18
|
+
when GroupedScope::SelfGroupping then "IN (?)"
|
19
|
+
else attribute_condition_without_grouped_scope(argument)
|
20
|
+
end
|
12
21
|
end
|
13
22
|
end
|
14
|
-
|
15
23
|
alias_method_chain :attribute_condition, :grouped_scope
|
16
24
|
|
17
25
|
end
|
@@ -9,12 +9,10 @@ module GroupedScope
|
|
9
9
|
|
10
10
|
def construct_sql_with_group_scope
|
11
11
|
if @reflection.options[:grouped_scope]
|
12
|
-
# CHANGED [Rails 1.2.6] Account for quoted_table_name.
|
13
|
-
table_name = @reflection.respond_to?(:quoted_table_name) ? @reflection.quoted_table_name : @reflection.klass.table_name
|
14
12
|
if @reflection.options[:as]
|
15
13
|
# TODO: Need to add case for polymorphic :as option.
|
16
14
|
else
|
17
|
-
@finder_sql = "#{
|
15
|
+
@finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} IN (#{@owner.group.quoted_ids})"
|
18
16
|
@finder_sql << " AND (#{conditions})" if conditions
|
19
17
|
end
|
20
18
|
@counter_sql = @finder_sql
|
@@ -40,8 +40,6 @@ class GroupedScope::AssociationReflectionTest < GroupedScope::TestCase
|
|
40
40
|
should 'delegate instance methods to #ungrouped_reflection' do
|
41
41
|
methods = [:class_name,:klass,:table_name,:primary_key_name,:active_record,
|
42
42
|
:association_foreign_key,:counter_cache_column,:source_reflection]
|
43
|
-
# CHANGED [Rails 1.2.6] Account for quoted_table_name.
|
44
|
-
methods << :quoted_table_name if @ungrouped_reflection.respond_to?(:quoted_table_name)
|
45
43
|
methods.each do |m|
|
46
44
|
assert_equal @ungrouped_reflection.send(m), @grouped_reflection.send(m),
|
47
45
|
"The method #{m.inspect} does not appear to be proxied to the ungrouped reflection."
|
@@ -54,17 +52,11 @@ class GroupedScope::AssociationReflectionTest < GroupedScope::TestCase
|
|
54
52
|
end
|
55
53
|
|
56
54
|
should 'derive class name to same as ungrouped reflection' do
|
57
|
-
|
58
|
-
if @ungrouped_reflection.respond_to?(:derive_class_name)
|
59
|
-
assert_equal @ungrouped_reflection.send(:derive_class_name), @grouped_reflection.send(:derive_class_name)
|
60
|
-
end
|
55
|
+
assert_equal @ungrouped_reflection.send(:derive_class_name), @grouped_reflection.send(:derive_class_name)
|
61
56
|
end
|
62
57
|
|
63
58
|
should 'derive primary key name to same as ungrouped reflection' do
|
64
|
-
|
65
|
-
if @ungrouped_reflection.respond_to?(:derive_primary_key_name)
|
66
|
-
assert_equal @ungrouped_reflection.send(:derive_primary_key_name), @grouped_reflection.send(:derive_primary_key_name)
|
67
|
-
end
|
59
|
+
assert_equal @ungrouped_reflection.send(:derive_primary_key_name), @grouped_reflection.send(:derive_primary_key_name)
|
68
60
|
end
|
69
61
|
|
70
62
|
should 'honor explicit legacy reports association options like class_name and foreign_key' do
|
data/test/lib/boot.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metaskills-grouped_scope
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ken Collins
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-05-06 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -75,10 +75,4 @@ test_files:
|
|
75
75
|
- test/grouped_scope/self_grouping_test.rb
|
76
76
|
- test/helper.rb
|
77
77
|
- test/lib/boot.rb
|
78
|
-
- test/lib/core_ext.rb
|
79
|
-
- test/lib/named_scope.rb
|
80
|
-
- test/lib/named_scope/core_ext.rb
|
81
|
-
- test/lib/named_scope/named_scope.rb
|
82
|
-
- test/lib/named_scope/named_scope_patch_1.2.rb
|
83
|
-
- test/lib/named_scope/named_scope_patch_2.0.rb
|
84
78
|
- test/lib/test_case.rb
|
data/test/lib/core_ext.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
|
2
|
-
unless Hash.instance_methods.include? 'except'
|
3
|
-
|
4
|
-
Hash.class_eval do
|
5
|
-
|
6
|
-
# Returns a new hash without the given keys.
|
7
|
-
def except(*keys)
|
8
|
-
rejected = Set.new(respond_to?(:convert_key) ? keys.map { |key| convert_key(key) } : keys)
|
9
|
-
reject { |key,| rejected.include?(key) }
|
10
|
-
end
|
11
|
-
|
12
|
-
# Replaces the hash without only the given keys.
|
13
|
-
def except!(*keys)
|
14
|
-
replace(except(*keys))
|
15
|
-
end
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
|
data/test/lib/named_scope.rb
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
unless defined? ActiveRecord::NamedScope
|
2
|
-
require "named_scope/core_ext"
|
3
|
-
require "named_scope/named_scope"
|
4
|
-
require "named_scope/named_scope_patch_#{ActiveRecord::Base.respond_to?(:find_first) ? '1.2' : '2.0'}"
|
5
|
-
ActiveRecord::Base.send :include, ActiveRecord::NamedScope
|
6
|
-
end
|
7
|
-
|
@@ -1,82 +0,0 @@
|
|
1
|
-
|
2
|
-
unless Hash.instance_methods.include? 'except'
|
3
|
-
Hash.class_eval do
|
4
|
-
|
5
|
-
# Returns a new hash without the given keys.
|
6
|
-
def except(*keys)
|
7
|
-
rejected = Set.new(respond_to?(:convert_key) ? keys.map { |key| convert_key(key) } : keys)
|
8
|
-
reject { |key,| rejected.include?(key) }
|
9
|
-
end
|
10
|
-
|
11
|
-
# Replaces the hash without only the given keys.
|
12
|
-
def except!(*keys)
|
13
|
-
replace(except(*keys))
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
class ActiveRecord::Base
|
20
|
-
class << self
|
21
|
-
|
22
|
-
def first(*args)
|
23
|
-
find(:first, *args)
|
24
|
-
end
|
25
|
-
|
26
|
-
def last(*args)
|
27
|
-
find(:last, *args)
|
28
|
-
end
|
29
|
-
|
30
|
-
def all(*args)
|
31
|
-
find(:all, *args)
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def find_last(options)
|
37
|
-
order = options[:order]
|
38
|
-
if order
|
39
|
-
order = reverse_sql_order(order)
|
40
|
-
elsif !scoped?(:find, :order)
|
41
|
-
order = "#{table_name}.#{primary_key} DESC"
|
42
|
-
end
|
43
|
-
if scoped?(:find, :order)
|
44
|
-
scoped_order = reverse_sql_order(scope(:find, :order))
|
45
|
-
scoped_methods.select { |s| s[:find].update(:order => scoped_order) }
|
46
|
-
end
|
47
|
-
find_initial(options.merge({ :order => order }))
|
48
|
-
end
|
49
|
-
|
50
|
-
def reverse_sql_order(order_query)
|
51
|
-
reversed_query = order_query.split(/,/).each { |s|
|
52
|
-
if s.match(/\s(asc|ASC)$/)
|
53
|
-
s.gsub!(/\s(asc|ASC)$/, ' DESC')
|
54
|
-
elsif s.match(/\s(desc|DESC)$/)
|
55
|
-
s.gsub!(/\s(desc|DESC)$/, ' ASC')
|
56
|
-
elsif !s.match(/\s(asc|ASC|desc|DESC)$/)
|
57
|
-
s.concat(' DESC')
|
58
|
-
end
|
59
|
-
}.join(',')
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
ActiveRecord::Associations::AssociationCollection.class_eval do
|
66
|
-
|
67
|
-
def last(*args)
|
68
|
-
if fetch_first_or_last_using_find? args
|
69
|
-
find(:last, *args)
|
70
|
-
else
|
71
|
-
load_target unless loaded?
|
72
|
-
@target.last(*args)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
private
|
77
|
-
|
78
|
-
def fetch_first_or_last_using_find?(args)
|
79
|
-
args.first.kind_of?(Hash) || !(loaded? || @owner.new_record? || @reflection.options[:finder_sql] || !@target.blank? || args.first.kind_of?(Integer))
|
80
|
-
end
|
81
|
-
|
82
|
-
end
|
@@ -1,168 +0,0 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module NamedScope
|
3
|
-
# All subclasses of ActiveRecord::Base have two named_scopes:
|
4
|
-
# * <tt>all</tt>, which is similar to a <tt>find(:all)</tt> query, and
|
5
|
-
# * <tt>scoped</tt>, which allows for the creation of anonymous scopes, on the fly: <tt>Shirt.scoped(:conditions => {:color => 'red'}).scoped(:include => :washing_instructions)</tt>
|
6
|
-
#
|
7
|
-
# These anonymous scopes tend to be useful when procedurally generating complex queries, where passing
|
8
|
-
# intermediate values (scopes) around as first-class objects is convenient.
|
9
|
-
def self.included(base)
|
10
|
-
base.class_eval do
|
11
|
-
extend ClassMethods
|
12
|
-
named_scope :scoped, lambda { |scope| scope }
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
module ClassMethods
|
17
|
-
def scopes
|
18
|
-
read_inheritable_attribute(:scopes) || write_inheritable_attribute(:scopes, {})
|
19
|
-
end
|
20
|
-
|
21
|
-
# Adds a class method for retrieving and querying objects. A scope represents a narrowing of a database query,
|
22
|
-
# such as <tt>:conditions => {:color => :red}, :select => 'shirts.*', :include => :washing_instructions</tt>.
|
23
|
-
#
|
24
|
-
# class Shirt < ActiveRecord::Base
|
25
|
-
# named_scope :red, :conditions => {:color => 'red'}
|
26
|
-
# named_scope :dry_clean_only, :joins => :washing_instructions, :conditions => ['washing_instructions.dry_clean_only = ?', true]
|
27
|
-
# end
|
28
|
-
#
|
29
|
-
# The above calls to <tt>named_scope</tt> define class methods <tt>Shirt.red</tt> and <tt>Shirt.dry_clean_only</tt>. <tt>Shirt.red</tt>,
|
30
|
-
# in effect, represents the query <tt>Shirt.find(:all, :conditions => {:color => 'red'})</tt>.
|
31
|
-
#
|
32
|
-
# Unlike Shirt.find(...), however, the object returned by <tt>Shirt.red</tt> is not an Array; it resembles the association object
|
33
|
-
# constructed by a <tt>has_many</tt> declaration. For instance, you can invoke <tt>Shirt.red.find(:first)</tt>, <tt>Shirt.red.count</tt>,
|
34
|
-
# <tt>Shirt.red.find(:all, :conditions => {:size => 'small'})</tt>. Also, just
|
35
|
-
# as with the association objects, name scopes acts like an Array, implementing Enumerable; <tt>Shirt.red.each(&block)</tt>,
|
36
|
-
# <tt>Shirt.red.first</tt>, and <tt>Shirt.red.inject(memo, &block)</tt> all behave as if Shirt.red really were an Array.
|
37
|
-
#
|
38
|
-
# These named scopes are composable. For instance, <tt>Shirt.red.dry_clean_only</tt> will produce all shirts that are both red and dry clean only.
|
39
|
-
# Nested finds and calculations also work with these compositions: <tt>Shirt.red.dry_clean_only.count</tt> returns the number of garments
|
40
|
-
# for which these criteria obtain. Similarly with <tt>Shirt.red.dry_clean_only.average(:thread_count)</tt>.
|
41
|
-
#
|
42
|
-
# All scopes are available as class methods on the ActiveRecord::Base descendent upon which the scopes were defined. But they are also available to
|
43
|
-
# <tt>has_many</tt> associations. If,
|
44
|
-
#
|
45
|
-
# class Person < ActiveRecord::Base
|
46
|
-
# has_many :shirts
|
47
|
-
# end
|
48
|
-
#
|
49
|
-
# then <tt>elton.shirts.red.dry_clean_only</tt> will return all of Elton's red, dry clean
|
50
|
-
# only shirts.
|
51
|
-
#
|
52
|
-
# Named scopes can also be procedural.
|
53
|
-
#
|
54
|
-
# class Shirt < ActiveRecord::Base
|
55
|
-
# named_scope :colored, lambda { |color|
|
56
|
-
# { :conditions => { :color => color } }
|
57
|
-
# }
|
58
|
-
# end
|
59
|
-
#
|
60
|
-
# In this example, <tt>Shirt.colored('puce')</tt> finds all puce shirts.
|
61
|
-
#
|
62
|
-
# Named scopes can also have extensions, just as with <tt>has_many</tt> declarations:
|
63
|
-
#
|
64
|
-
# class Shirt < ActiveRecord::Base
|
65
|
-
# named_scope :red, :conditions => {:color => 'red'} do
|
66
|
-
# def dom_id
|
67
|
-
# 'red_shirts'
|
68
|
-
# end
|
69
|
-
# end
|
70
|
-
# end
|
71
|
-
#
|
72
|
-
#
|
73
|
-
# For testing complex named scopes, you can examine the scoping options using the
|
74
|
-
# <tt>proxy_options</tt> method on the proxy itself.
|
75
|
-
#
|
76
|
-
# class Shirt < ActiveRecord::Base
|
77
|
-
# named_scope :colored, lambda { |color|
|
78
|
-
# { :conditions => { :color => color } }
|
79
|
-
# }
|
80
|
-
# end
|
81
|
-
#
|
82
|
-
# expected_options = { :conditions => { :colored => 'red' } }
|
83
|
-
# assert_equal expected_options, Shirt.colored('red').proxy_options
|
84
|
-
def named_scope(name, options = {}, &block)
|
85
|
-
name = name.to_sym
|
86
|
-
scopes[name] = lambda do |parent_scope, *args|
|
87
|
-
Scope.new(parent_scope, case options
|
88
|
-
when Hash
|
89
|
-
options
|
90
|
-
when Proc
|
91
|
-
options.call(*args)
|
92
|
-
end, &block)
|
93
|
-
end
|
94
|
-
(class << self; self end).instance_eval do
|
95
|
-
define_method name do |*args|
|
96
|
-
scopes[name].call(self, *args)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
class Scope
|
103
|
-
attr_reader :proxy_scope, :proxy_options
|
104
|
-
|
105
|
-
[].methods.each do |m|
|
106
|
-
unless m =~ /(^__|^nil\?|^send|^object_id$|class|extend|^find$|count|sum|average|maximum|minimum|paginate|first|last|empty\?|respond_to\?)/
|
107
|
-
delegate m, :to => :proxy_found
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
delegate :scopes, :with_scope, :to => :proxy_scope
|
112
|
-
|
113
|
-
def initialize(proxy_scope, options, &block)
|
114
|
-
[options[:extend]].flatten.each { |extension| extend extension } if options[:extend]
|
115
|
-
extend Module.new(&block) if block_given?
|
116
|
-
@proxy_scope, @proxy_options = proxy_scope, options.except(:extend)
|
117
|
-
end
|
118
|
-
|
119
|
-
def reload
|
120
|
-
load_found; self
|
121
|
-
end
|
122
|
-
|
123
|
-
def first(*args)
|
124
|
-
if args.first.kind_of?(Integer) || (@found && !args.first.kind_of?(Hash))
|
125
|
-
proxy_found.first(*args)
|
126
|
-
else
|
127
|
-
find(:first, *args)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
def last(*args)
|
132
|
-
if args.first.kind_of?(Integer) || (@found && !args.first.kind_of?(Hash))
|
133
|
-
proxy_found.last(*args)
|
134
|
-
else
|
135
|
-
find(:last, *args)
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
def empty?
|
140
|
-
@found ? @found.empty? : count.zero?
|
141
|
-
end
|
142
|
-
|
143
|
-
def respond_to?(method, include_private = false)
|
144
|
-
super || @proxy_scope.respond_to?(method, include_private)
|
145
|
-
end
|
146
|
-
|
147
|
-
protected
|
148
|
-
def proxy_found
|
149
|
-
@found || load_found
|
150
|
-
end
|
151
|
-
|
152
|
-
private
|
153
|
-
def method_missing(method, *args, &block)
|
154
|
-
if scopes.include?(method)
|
155
|
-
scopes[method].call(self, *args)
|
156
|
-
else
|
157
|
-
with_scope :find => proxy_options do
|
158
|
-
proxy_scope.send(method, *args, &block)
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
def load_found
|
164
|
-
@found = find(:all)
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
@@ -1,85 +0,0 @@
|
|
1
|
-
|
2
|
-
ActiveRecord::Associations::AssociationProxy.class_eval do
|
3
|
-
protected
|
4
|
-
def with_scope(*args, &block)
|
5
|
-
@reflection.klass.send :with_scope, *args, &block
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
class ActiveRecord::Base
|
10
|
-
class << self
|
11
|
-
def find(*args)
|
12
|
-
options = extract_options_from_args!(args)
|
13
|
-
validate_find_options(options)
|
14
|
-
set_readonly_option!(options)
|
15
|
-
case args.first
|
16
|
-
when :first then find_initial(options)
|
17
|
-
when :last then find_last(options)
|
18
|
-
when :all then find_every(options)
|
19
|
-
else find_from_ids(args, options)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
private
|
23
|
-
def attribute_condition_with_named_scope(argument)
|
24
|
-
case argument
|
25
|
-
when ActiveRecord::Associations::AssociationCollection, ActiveRecord::NamedScope::Scope then "IN (?)"
|
26
|
-
else attribute_condition_without_named_scope(argument)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
alias_method_chain :attribute_condition, :named_scope
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
ActiveRecord::Associations::HasManyAssociation.class_eval do
|
34
|
-
protected
|
35
|
-
def method_missing(method, *args, &block)
|
36
|
-
if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method))
|
37
|
-
super
|
38
|
-
elsif @reflection.klass.scopes.include?(method)
|
39
|
-
@reflection.klass.scopes[method].call(self, *args)
|
40
|
-
else
|
41
|
-
create_scoping = {}
|
42
|
-
set_belongs_to_association_for(create_scoping)
|
43
|
-
|
44
|
-
@reflection.klass.with_scope(
|
45
|
-
:create => create_scoping,
|
46
|
-
:find => {
|
47
|
-
:conditions => @finder_sql,
|
48
|
-
:joins => @join_sql,
|
49
|
-
:readonly => false
|
50
|
-
}
|
51
|
-
) do
|
52
|
-
@reflection.klass.send(method, *args, &block)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
ActiveRecord::Associations::HasManyThroughAssociation.class_eval do
|
59
|
-
protected
|
60
|
-
def method_missing(method, *args, &block)
|
61
|
-
if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method))
|
62
|
-
super
|
63
|
-
elsif @reflection.klass.scopes.include?(method)
|
64
|
-
@reflection.klass.scopes[method].call(self, *args)
|
65
|
-
else
|
66
|
-
@reflection.klass.with_scope(construct_scope) { @reflection.klass.send(method, *args, &block) }
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
ActiveRecord::Associations::HasAndBelongsToManyAssociation.class_eval do
|
72
|
-
protected
|
73
|
-
def method_missing(method, *args, &block)
|
74
|
-
if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method))
|
75
|
-
super
|
76
|
-
elsif @reflection.klass.scopes.include?(method)
|
77
|
-
@reflection.klass.scopes[method].call(self, *args)
|
78
|
-
else
|
79
|
-
@reflection.klass.with_scope(:find => { :conditions => @finder_sql, :joins => @join_sql, :readonly => false }) do
|
80
|
-
@reflection.klass.send(method, *args, &block)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
@@ -1,55 +0,0 @@
|
|
1
|
-
|
2
|
-
ActiveRecord::Associations::AssociationProxy.class_eval do
|
3
|
-
protected
|
4
|
-
def with_scope(*args, &block)
|
5
|
-
@reflection.klass.send :with_scope, *args, &block
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
class ActiveRecord::Base
|
10
|
-
class << self
|
11
|
-
def find(*args)
|
12
|
-
options = args.extract_options!
|
13
|
-
validate_find_options(options)
|
14
|
-
set_readonly_option!(options)
|
15
|
-
case args.first
|
16
|
-
when :first then find_initial(options)
|
17
|
-
when :last then find_last(options)
|
18
|
-
when :all then find_every(options)
|
19
|
-
else find_from_ids(args, options)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
private
|
23
|
-
def attribute_condition_with_named_scope(argument)
|
24
|
-
case argument
|
25
|
-
when ActiveRecord::NamedScope::Scope then "IN (?)"
|
26
|
-
else attribute_condition_without_named_scope(argument)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
alias_method_chain :attribute_condition, :named_scope
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
ActiveRecord::Associations::AssociationCollection.class_eval do
|
34
|
-
protected
|
35
|
-
def method_missing(method, *args)
|
36
|
-
if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method))
|
37
|
-
if block_given?
|
38
|
-
super { |*block_args| yield(*block_args) }
|
39
|
-
else
|
40
|
-
super
|
41
|
-
end
|
42
|
-
elsif @reflection.klass.scopes.include?(method)
|
43
|
-
@reflection.klass.scopes[method].call(self, *args)
|
44
|
-
else
|
45
|
-
with_scope(construct_scope) do
|
46
|
-
if block_given?
|
47
|
-
@reflection.klass.send(method, *args) { |*block_args| yield(*block_args) }
|
48
|
-
else
|
49
|
-
@reflection.klass.send(method, *args)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|