store_base_sti_class 0.5.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +5 -57
  3. data/Gemfile.lock +6 -9
  4. data/README.md +8 -11
  5. data/debug.log +12652 -0
  6. data/gemfiles/rails_3.0.5.gemfile.lock +3 -3
  7. data/gemfiles/rails_3.0.6.gemfile.lock +3 -3
  8. data/gemfiles/rails_3.0.7.gemfile.lock +3 -3
  9. data/gemfiles/rails_3.2.14.gemfile.lock +1 -4
  10. data/gemfiles/rails_4.0.0.gemfile.lock +2 -5
  11. data/gemfiles/rails_4.0.1.gemfile.lock +2 -5
  12. data/gemfiles/rails_4.0.10.gemfile.lock +2 -5
  13. data/gemfiles/rails_4.0.11.1.gemfile.lock +2 -5
  14. data/gemfiles/rails_4.0.11.gemfile.lock +2 -5
  15. data/gemfiles/rails_4.0.12.gemfile.lock +2 -5
  16. data/gemfiles/rails_4.0.13.gemfile.lock +2 -5
  17. data/gemfiles/rails_4.0.2.gemfile.lock +2 -5
  18. data/gemfiles/rails_4.0.3.gemfile.lock +2 -5
  19. data/gemfiles/rails_4.0.4.gemfile.lock +2 -5
  20. data/gemfiles/rails_4.0.5.gemfile.lock +2 -5
  21. data/gemfiles/rails_4.0.6.gemfile.lock +2 -5
  22. data/gemfiles/rails_4.0.7.gemfile.lock +2 -5
  23. data/gemfiles/rails_4.0.8.gemfile.lock +2 -5
  24. data/gemfiles/rails_4.0.9.gemfile.lock +2 -5
  25. data/gemfiles/rails_4.1.0.gemfile.lock +2 -5
  26. data/gemfiles/rails_4.1.1.gemfile.lock +2 -5
  27. data/gemfiles/rails_4.1.10.gemfile.lock +2 -5
  28. data/gemfiles/rails_4.1.11.gemfile.lock +2 -5
  29. data/gemfiles/rails_4.1.12.gemfile.lock +2 -5
  30. data/gemfiles/rails_4.1.13.gemfile.lock +48 -0
  31. data/gemfiles/rails_4.1.14.1.gemfile.lock +48 -0
  32. data/gemfiles/rails_4.1.14.2.gemfile.lock +48 -0
  33. data/gemfiles/rails_4.1.14.gemfile.lock +48 -0
  34. data/gemfiles/rails_4.1.15.gemfile.lock +48 -0
  35. data/gemfiles/rails_4.1.2.gemfile.lock +2 -5
  36. data/gemfiles/rails_4.1.3.gemfile.lock +2 -5
  37. data/gemfiles/rails_4.1.4.gemfile.lock +2 -5
  38. data/gemfiles/rails_4.1.5.gemfile.lock +2 -5
  39. data/gemfiles/rails_4.1.6.gemfile.lock +2 -5
  40. data/gemfiles/rails_4.1.7.1.gemfile.lock +2 -5
  41. data/gemfiles/rails_4.1.7.gemfile.lock +2 -5
  42. data/gemfiles/rails_4.1.8.gemfile.lock +2 -5
  43. data/gemfiles/rails_4.1.9.gemfile.lock +2 -5
  44. data/gemfiles/rails_4.2.0.gemfile.lock +2 -5
  45. data/gemfiles/rails_4.2.1.gemfile.lock +2 -5
  46. data/gemfiles/rails_4.2.2.gemfile.lock +2 -5
  47. data/gemfiles/rails_4.2.3.gemfile.lock +2 -5
  48. data/gemfiles/rails_4.2.4.gemfile.lock +48 -0
  49. data/gemfiles/rails_4.2.5.1.gemfile.lock +48 -0
  50. data/gemfiles/rails_4.2.5.2.gemfile.lock +48 -0
  51. data/gemfiles/rails_4.2.5.gemfile.lock +48 -0
  52. data/gemfiles/rails_4.2.6.gemfile.lock +48 -0
  53. data/gemfiles/{rails_3.0.5.gemfile → rails_4.2.7.1.gemfile} +1 -2
  54. data/gemfiles/{rails_3.0.6.gemfile → rails_4.2.7.gemfile} +1 -2
  55. data/gemfiles/{rails_3.0.7.gemfile → rails_5.0.0.1.gemfile} +1 -2
  56. data/gemfiles/{rails_3.0.8.gemfile → rails_5.0.0.gemfile} +1 -2
  57. data/gemfiles/rails_5.0.1.gemfile +7 -0
  58. data/gemfiles/rails_5.0.1.gemfile.lock +48 -0
  59. data/lib/store_base_sti_class.rb +3 -5
  60. data/lib/store_base_sti_class/version.rb +1 -1
  61. data/lib/store_base_sti_class_for_5_0.rb +404 -0
  62. data/store_base_sti_class.gemspec +3 -3
  63. data/storebasestiname_unittest.sql +0 -0
  64. metadata +26 -64
  65. data/gemfiles/rails_3.0.10.gemfile +0 -8
  66. data/gemfiles/rails_3.0.11.gemfile +0 -8
  67. data/gemfiles/rails_3.0.12.gemfile +0 -8
  68. data/gemfiles/rails_3.0.13.gemfile +0 -8
  69. data/gemfiles/rails_3.0.14.gemfile +0 -8
  70. data/gemfiles/rails_3.0.15.gemfile +0 -8
  71. data/gemfiles/rails_3.0.16.gemfile +0 -8
  72. data/gemfiles/rails_3.0.17.gemfile +0 -8
  73. data/gemfiles/rails_3.0.18.gemfile +0 -8
  74. data/gemfiles/rails_3.0.19.gemfile +0 -8
  75. data/gemfiles/rails_3.0.20.gemfile +0 -8
  76. data/gemfiles/rails_3.0.9.gemfile +0 -8
  77. data/gemfiles/rails_3.1.0.gemfile +0 -8
  78. data/gemfiles/rails_3.1.10.gemfile +0 -8
  79. data/gemfiles/rails_3.1.11.gemfile +0 -8
  80. data/gemfiles/rails_3.1.12.gemfile +0 -8
  81. data/gemfiles/rails_3.1.2.gemfile +0 -8
  82. data/gemfiles/rails_3.1.3.gemfile +0 -8
  83. data/gemfiles/rails_3.1.4.gemfile +0 -8
  84. data/gemfiles/rails_3.1.5.gemfile +0 -8
  85. data/gemfiles/rails_3.1.6.gemfile +0 -8
  86. data/gemfiles/rails_3.1.7.gemfile +0 -8
  87. data/gemfiles/rails_3.1.8.gemfile +0 -8
  88. data/gemfiles/rails_3.1.9.gemfile +0 -8
  89. data/gemfiles/rails_3.2.0.gemfile +0 -8
  90. data/gemfiles/rails_3.2.1.gemfile +0 -8
  91. data/gemfiles/rails_3.2.10.gemfile +0 -8
  92. data/gemfiles/rails_3.2.11.gemfile +0 -8
  93. data/gemfiles/rails_3.2.12.gemfile +0 -8
  94. data/gemfiles/rails_3.2.13.gemfile +0 -8
  95. data/gemfiles/rails_3.2.14.gemfile +0 -8
  96. data/gemfiles/rails_3.2.15.gemfile +0 -8
  97. data/gemfiles/rails_3.2.16.gemfile +0 -8
  98. data/gemfiles/rails_3.2.17.gemfile +0 -8
  99. data/gemfiles/rails_3.2.18.gemfile +0 -8
  100. data/gemfiles/rails_3.2.19.gemfile +0 -8
  101. data/gemfiles/rails_3.2.2.gemfile +0 -8
  102. data/gemfiles/rails_3.2.20.gemfile +0 -8
  103. data/gemfiles/rails_3.2.21.gemfile +0 -8
  104. data/gemfiles/rails_3.2.22.1.gemfile +0 -8
  105. data/gemfiles/rails_3.2.22.2.gemfile +0 -8
  106. data/gemfiles/rails_3.2.22.gemfile +0 -8
  107. data/gemfiles/rails_3.2.3.gemfile +0 -8
  108. data/gemfiles/rails_3.2.4.gemfile +0 -8
  109. data/gemfiles/rails_3.2.5.gemfile +0 -8
  110. data/gemfiles/rails_3.2.6.gemfile +0 -8
  111. data/gemfiles/rails_3.2.7.gemfile +0 -8
  112. data/gemfiles/rails_3.2.8.gemfile +0 -8
  113. data/gemfiles/rails_3.2.9.gemfile +0 -8
  114. data/lib/store_base_sti_class_for_3_0.rb +0 -470
  115. data/lib/store_base_sti_class_for_3_1_and_above.rb +0 -304
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.1.7"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.1.8"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.1.9"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.0"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.1"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.10"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.11"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.12"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.13"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.14"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.15"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.16"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.17"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.18"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.19"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.2"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.20"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.21"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.22.1"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.22.2"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.22"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.3"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.4"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.5"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.6"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.7"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.8"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "3.2.9"
6
- gem "minitest", "~> 4.0"
7
-
8
- gemspec :path => "../"
@@ -1,470 +0,0 @@
1
- require 'active_record'
2
-
3
- if ActiveRecord::VERSION::STRING =~ /^3\.0/
4
- require 'active_record/associations'
5
- require 'active_record/reflection'
6
- require 'active_record/association_preload'
7
- require 'active_record/associations/has_many_association'
8
- require 'active_record/associations/has_one_association'
9
- require 'active_record/associations/through_association_scope'
10
- require 'active_record/associations/association_proxy'
11
- require 'active_record/associations/belongs_to_polymorphic_association'
12
-
13
- class ActiveRecord::Base
14
-
15
- # Determine whether to store the base class or the actual class in polymorhic type columns when using STI
16
- superclass_delegating_accessor :store_base_sti_class
17
- self.store_base_sti_class = true
18
-
19
- class << self
20
-
21
- def polymorphic_sti_name
22
- store_base_sti_class ? base_class.sti_name : sti_name
23
- end
24
-
25
- def in_or_equals_sti_names
26
- if store_base_sti_class
27
- "= #{quote_value(base_class.sti_name)}"
28
- else
29
- names = sti_names.map { |name| quote_value(name) }
30
- names.length > 1 ? "IN (#{names.join(',')})" : "= #{names.first}"
31
- end
32
- end
33
-
34
- def sti_names
35
- ([self] + descendants).map { |model| model.sti_name }
36
- end
37
-
38
- end
39
-
40
- end
41
-
42
- module ActiveRecord
43
- module Reflection
44
- class AssociationReflection < MacroReflection #:nodoc:
45
-
46
- def active_record_primary_key
47
- @active_record_primary_key ||= options[:primary_key] || active_record.primary_key
48
- end
49
-
50
- end
51
- end
52
- end
53
-
54
- module ActiveRecord
55
- module AssociationPreload
56
- module ClassMethods
57
-
58
- private
59
-
60
- def preload_through_records(records, reflection, through_association)
61
- # p 'preload_through_records'
62
- through_reflection = reflections[through_association]
63
- through_primary_key = through_reflection.primary_key_name
64
-
65
- through_records = []
66
- if reflection.options[:source_type]
67
- interface = reflection.source_reflection.options[:foreign_type]
68
- source_type = reflection.options[:source_type].to_s.constantize
69
- preload_options = { :conditions => "#{connection.quote_column_name interface} #{source_type.in_or_equals_sti_names}" }
70
-
71
- records.compact!
72
- records.first.class.preload_associations(records, through_association, preload_options)
73
-
74
- # Dont cache the association - we would only be caching a subset
75
- records.each do |record|
76
- proxy = record.send(through_association)
77
-
78
- if proxy.respond_to?(:target)
79
- through_records.concat Array.wrap(proxy.target)
80
- proxy.reset
81
- else # this is a has_one :through reflection
82
- through_records << proxy if proxy
83
- end
84
- end
85
- else
86
- options = {}
87
- options[:include] = reflection.options[:include] || reflection.options[:source] if reflection.options[:conditions] || reflection.options[:order]
88
- options[:order] = reflection.options[:order]
89
- options[:conditions] = reflection.options[:conditions]
90
- records.first.class.preload_associations(records, through_association, options)
91
-
92
- records.each do |record|
93
- through_records.concat Array.wrap(record.send(through_association))
94
- end
95
- end
96
- through_records
97
- end
98
-
99
- def find_associated_records(ids, reflection, preload_options)
100
- # p 'find_associated_records'
101
- options = reflection.options
102
- table_name = reflection.klass.quoted_table_name
103
-
104
- if interface = reflection.options[:as]
105
- conditions = "#{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_id"} #{in_or_equals_for_ids(ids)} and #{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_type"} #{self.in_or_equals_sti_names}"
106
- else
107
- foreign_key = reflection.primary_key_name
108
- conditions = "#{reflection.klass.quoted_table_name}.#{foreign_key} #{in_or_equals_for_ids(ids)}"
109
- end
110
-
111
- # p 'append_conditions'
112
- conditions << append_conditions(reflection, preload_options)
113
-
114
- find_options = {
115
- :select => preload_options[:select] || options[:select] || Arel::SqlLiteral.new("#{table_name}.*"),
116
- :include => preload_options[:include] || options[:include],
117
- :joins => options[:joins],
118
- :group => preload_options[:group] || options[:group],
119
- :order => preload_options[:order] || options[:order]
120
- }
121
-
122
- # p 'associated_records'
123
- associated_records(ids) do |some_ids|
124
- reflection.klass.scoped.apply_finder_options(find_options.merge(:conditions => [conditions, some_ids])).to_a
125
- end
126
- end
127
-
128
- end
129
- end
130
- end
131
-
132
- module ActiveRecord
133
- module Associations
134
- class HasManyAssociation < AssociationCollection
135
-
136
- protected
137
-
138
- def construct_sql
139
- # p 'construct_sql :has_many'
140
-
141
- case
142
- when @reflection.options[:finder_sql]
143
- @finder_sql = interpolate_and_sanitize_sql(@reflection.options[:finder_sql])
144
-
145
- when @reflection.options[:as]
146
- @finder_sql =
147
- "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_id = #{owner_quoted_id} AND " +
148
- "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_type #{@owner.class.in_or_equals_sti_names}"
149
- @finder_sql << " AND (#{conditions})" if conditions
150
-
151
- else
152
- @finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{owner_quoted_id}"
153
- @finder_sql << " AND (#{conditions})" if conditions
154
- end
155
-
156
- construct_counter_sql
157
- end
158
-
159
- end
160
- end
161
- end
162
-
163
- module ActiveRecord
164
- module Associations
165
- class HasOneAssociation < AssociationProxy
166
-
167
- protected
168
-
169
- def construct_sql
170
- # p 'construct_sql :has_one'
171
-
172
- case
173
- when @reflection.options[:as]
174
- @finder_sql =
175
- "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_id = #{owner_quoted_id} AND " +
176
- "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_type #{@owner.class.in_or_equals_sti_names}"
177
- else
178
- @finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{owner_quoted_id}"
179
- end
180
- @finder_sql << " AND (#{conditions})" if conditions
181
- end
182
-
183
- end
184
- end
185
- end
186
-
187
- module ActiveRecord
188
- module Associations
189
- module ThroughAssociationScope
190
-
191
- protected
192
-
193
- def construct_quoted_owner_attributes(reflection)
194
- # p 'construct_quoted_owner_attributes'
195
-
196
- if as = reflection.options[:as]
197
- {
198
- "#{as}_id" => owner_quoted_id,
199
- "#{as}_type" => @owner.class.quote_value(@owner.class.polymorphic_sti_name)
200
- }
201
- elsif reflection.macro == :belongs_to
202
- { reflection.klass.primary_key => @owner.class.quote_value(@owner[reflection.primary_key_name]) }
203
- else
204
- { reflection.primary_key_name => owner_quoted_id }
205
- end
206
- end
207
-
208
- def construct_joins(custom_joins = nil)
209
- # p 'construct_joins'
210
-
211
- polymorphic_join = nil
212
- if @reflection.source_reflection.macro == :belongs_to
213
- reflection_primary_key = @reflection.klass.primary_key
214
- source_primary_key = @reflection.source_reflection.primary_key_name
215
- if @reflection.options[:source_type]
216
- source_type = @reflection.options[:source_type].to_s.constantize
217
- polymorphic_join = "AND %s.%s #{source_type.in_or_equals_sti_names}" % [
218
- @reflection.through_reflection.quoted_table_name,
219
- "#{@reflection.source_reflection.options[:foreign_type]}"
220
- ]
221
- end
222
- else
223
- reflection_primary_key = @reflection.source_reflection.primary_key_name
224
- source_primary_key = @reflection.through_reflection.klass.primary_key
225
- if @reflection.source_reflection.options[:as]
226
- polymorphic_join = "AND %s.%s #{@reflection.through_reflection.klass.in_or_equals_sti_names}" % [
227
- @reflection.quoted_table_name,
228
- "#{@reflection.source_reflection.options[:as]}_type"
229
- ]
230
- end
231
- end
232
-
233
- "INNER JOIN %s ON %s.%s = %s.%s %s #{@reflection.options[:joins]} #{custom_joins}" % [
234
- @reflection.through_reflection.quoted_table_name,
235
- @reflection.quoted_table_name, reflection_primary_key,
236
- @reflection.through_reflection.quoted_table_name, source_primary_key,
237
- polymorphic_join
238
- ]
239
- end
240
-
241
- def construct_owner_attributes(reflection)
242
- # p 'construct_owner_attributes'
243
-
244
- if as = reflection.options[:as]
245
- { "#{as}_id" => @owner.id,
246
- "#{as}_type" => @owner.class.polymorphic_sti_name }
247
- else
248
- { reflection.primary_key_name => @owner.id }
249
- end
250
- end
251
-
252
- end
253
- end
254
- end
255
-
256
- module ActiveRecord
257
- module Associations
258
- class AssociationProxy
259
-
260
- protected
261
-
262
- def set_belongs_to_association_for(record)
263
- # p 'set_belongs_to_association_for'
264
-
265
- if @reflection.options[:as]
266
- record["#{@reflection.options[:as]}_id"] = @owner.id unless @owner.new_record?
267
- record["#{@reflection.options[:as]}_type"] = @owner.class.polymorphic_sti_name
268
- else
269
- unless @owner.new_record?
270
- primary_key = @reflection.options[:primary_key] || :id
271
- record[@reflection.primary_key_name] = @owner.send(primary_key)
272
- end
273
- end
274
- end
275
-
276
- end
277
- end
278
- end
279
-
280
- module ActiveRecord
281
- module Associations
282
- class BelongsToPolymorphicAssociation < AssociationProxy
283
-
284
- def replace(record)
285
- # p 'replace'
286
-
287
- if record.nil?
288
- @target = @owner[@reflection.primary_key_name] = @owner[@reflection.options[:foreign_type]] = nil
289
- else
290
- @target = (AssociationProxy === record ? record.target : record)
291
-
292
- @owner[@reflection.primary_key_name] = record_id(record)
293
- @owner[@reflection.options[:foreign_type]] = record.class.polymorphic_sti_name
294
-
295
- @updated = true
296
- end
297
-
298
- set_inverse_instance(record, @owner)
299
- loaded
300
- record
301
- end
302
-
303
- end
304
- end
305
- end
306
-
307
- module ActiveRecord
308
- module Associations
309
- module ThroughAssociationScope
310
-
311
- protected
312
-
313
- def construct_quoted_owner_attributes(reflection)
314
- # p 'construct_quoted_owner_attributes'
315
- if as = reflection.options[:as]
316
- {
317
- "#{as}_id" => owner_quoted_id,
318
- "#{as}_type" => @owner.class.quote_value(@owner.class.polymorphic_sti_name)
319
- }
320
- elsif reflection.macro == :belongs_to
321
- { reflection.klass.primary_key => @owner.class.quote_value(@owner[reflection.primary_key_name]) }
322
- else
323
- { reflection.primary_key_name => owner_quoted_id }
324
- end
325
- end
326
-
327
- def construct_owner_attributes(reflection)
328
- # p 'construct_owner_attributes'
329
- if as = reflection.options[:as]
330
- { "#{as}_id" => @owner.id,
331
- "#{as}_type" => @owner.class.polymorphic_sti_name }
332
- else
333
- { reflection.primary_key_name => @owner.id }
334
- end
335
- end
336
-
337
- def construct_join_attributes(associate)
338
- # p 'construct_join_attributes'
339
- # TODO: revisit this to allow it for deletion, supposing dependent option is supported
340
- raise ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection.new(@owner, @reflection) if [:has_one, :has_many].include?(@reflection.source_reflection.macro)
341
-
342
- join_attributes = construct_owner_attributes(@reflection.through_reflection).merge(@reflection.source_reflection.primary_key_name => associate.id)
343
-
344
- if @reflection.options[:source_type]
345
- join_attributes.merge!(@reflection.source_reflection.options[:foreign_type] => associate.class.polymorphic_sti_name)
346
- end
347
-
348
- if @reflection.through_reflection.options[:conditions].is_a?(Hash)
349
- join_attributes.merge!(@reflection.through_reflection.options[:conditions])
350
- end
351
-
352
- join_attributes
353
- end
354
-
355
- end
356
- end
357
- end
358
-
359
- module ActiveRecord
360
- module Associations
361
- module ClassMethods
362
- class JoinDependency # :nodoc:
363
- class JoinAssociation < JoinBase # :nodoc:
364
-
365
- def association_join
366
- # p 'association_join'
367
-
368
- return @join if @join
369
-
370
- aliased_table = Arel::Table.new(table_name, :as => @aliased_table_name,
371
- :engine => arel_engine,
372
- :columns => klass.columns)
373
-
374
- parent_table = Arel::Table.new(parent.table_name, :as => parent.aliased_table_name,
375
- :engine => arel_engine,
376
- :columns => parent.active_record.columns)
377
-
378
- @join = case reflection.macro
379
- when :has_and_belongs_to_many
380
- join_table = Arel::Table.new(options[:join_table], :as => aliased_join_table_name, :engine => arel_engine)
381
- fk = options[:foreign_key] || reflection.active_record.to_s.foreign_key
382
- klass_fk = options[:association_foreign_key] || klass.to_s.foreign_key
383
-
384
- [
385
- join_table[fk].eq(parent_table[reflection.active_record.primary_key]),
386
- aliased_table[klass.primary_key].eq(join_table[klass_fk])
387
- ]
388
- when :has_many, :has_one
389
- if reflection.options[:through]
390
- join_table = Arel::Table.new(through_reflection.klass.table_name, :as => aliased_join_table_name, :engine => arel_engine)
391
- jt_as_extra = jt_source_extra = jt_sti_extra = nil
392
- first_key = second_key = nil
393
-
394
- if through_reflection.macro == :belongs_to
395
- jt_primary_key = through_reflection.primary_key_name
396
- jt_foreign_key = through_reflection.association_primary_key
397
- else
398
- jt_primary_key = through_reflection.active_record_primary_key
399
- jt_foreign_key = through_reflection.primary_key_name
400
-
401
- if through_reflection.options[:as] # has_many :through against a polymorphic join
402
- jt_as_extra = join_table[through_reflection.options[:as].to_s + '_type'].in(parent.active_record.sti_names)
403
- end
404
- end
405
-
406
- case source_reflection.macro
407
- when :has_many
408
- if source_reflection.options[:as]
409
- first_key = "#{source_reflection.options[:as]}_id"
410
- second_key = options[:foreign_key] || primary_key
411
- else
412
- first_key = through_reflection.klass.base_class.to_s.foreign_key
413
- second_key = options[:foreign_key] || primary_key
414
- end
415
-
416
- unless through_reflection.klass.descends_from_active_record?
417
- # there is no test for this condition
418
- jt_sti_extra = join_table[through_reflection.active_record.inheritance_column].eq(through_reflection.klass.sti_name)
419
- end
420
- when :belongs_to
421
- first_key = primary_key
422
- if reflection.options[:source_type]
423
- source_type = reflection.options[:source_type].to_s.constantize
424
- second_key = source_reflection.association_foreign_key
425
- jt_source_extra = join_table[reflection.source_reflection.options[:foreign_type]].in(source_type.sti_names)
426
- else
427
- second_key = source_reflection.primary_key_name
428
- end
429
- end
430
-
431
- [
432
- [parent_table[jt_primary_key].eq(join_table[jt_foreign_key]), jt_as_extra, jt_source_extra, jt_sti_extra].reject{|x| x.blank? },
433
- aliased_table[first_key].eq(join_table[second_key])
434
- ]
435
- elsif reflection.options[:as]
436
- id_rel = aliased_table["#{reflection.options[:as]}_id"].eq(parent_table[parent.primary_key])
437
- type_rel = aliased_table["#{reflection.options[:as]}_type"].in(parent.active_record.sti_names)
438
- [id_rel, type_rel]
439
- else
440
- foreign_key = options[:foreign_key] || reflection.active_record.name.foreign_key
441
- [aliased_table[foreign_key].eq(parent_table[reflection.options[:primary_key] || parent.primary_key])]
442
- end
443
- when :belongs_to
444
- [aliased_table[options[:primary_key] || reflection.klass.primary_key].eq(parent_table[options[:foreign_key] || reflection.primary_key_name])]
445
- end
446
-
447
- unless klass.descends_from_active_record?
448
- sti_column = aliased_table[klass.inheritance_column]
449
- sti_condition = sti_column.eq(klass.sti_name)
450
- klass.descendants.each {|subclass| sti_condition = sti_condition.or(sti_column.eq(subclass.sti_name)) }
451
-
452
- @join << sti_condition
453
- end
454
-
455
- [through_reflection, reflection].each do |ref|
456
- if ref && ref.options[:conditions]
457
- @join << process_conditions(ref.options[:conditions], aliased_table_name)
458
- end
459
- end
460
-
461
- @join
462
- end
463
-
464
- end
465
- end
466
- end
467
- end
468
- end
469
-
470
- end