# File lib/active_record/relation/query_methods.rb, line 109
109: def arel
110: @arel ||= build_arel
111: end
# File lib/active_record/relation/query_methods.rb, line 135
135: def build_arel
136: arel = table
137:
138: arel = build_joins(arel, @joins_values) unless @joins_values.empty?
139:
140: (@where_values - ['']).uniq.each do |where|
141: case where
142: when Arel::SqlLiteral
143: arel = arel.where(where)
144: else
145: sql = where.is_a?(String) ? where : where.to_sql
146: arel = arel.where(Arel::SqlLiteral.new("(#{sql})"))
147: end
148: end
149:
150: arel = arel.having(*@having_values.uniq.select{|h| h.present?}) unless @having_values.empty?
151:
152: arel = arel.take(@limit_value) if @limit_value
153: arel = arel.skip(@offset_value) if @offset_value
154:
155: arel = arel.group(*@group_values.uniq.select{|g| g.present?}) unless @group_values.empty?
156:
157: arel = arel.order(*@order_values.uniq.select{|o| o.present?}) unless @order_values.empty?
158:
159: arel = build_select(arel, @select_values.uniq)
160:
161: arel = arel.from(@from_value) if @from_value
162: arel = arel.lock(@lock_value) if @lock_value
163:
164: arel
165: end
# File lib/active_record/relation/query_methods.rb, line 167
167: def build_where(opts, other = [])
168: case opts
169: when String, Array
170: @klass.send(:sanitize_sql, other.empty? ? opts : ([opts] + other))
171: when Hash
172: attributes = @klass.send(:expand_hash_conditions_for_aggregates, opts)
173: PredicateBuilder.new(table.engine).build_from_hash(attributes, table)
174: else
175: opts
176: end
177: end
# File lib/active_record/relation/query_methods.rb, line 85
85: def create_with(value = true)
86: clone.tap {|r| r.create_with_value = value }
87: end
# File lib/active_record/relation/query_methods.rb, line 113
113: def custom_join_sql(*joins)
114: arel = table
115: joins.each do |join|
116: next if join.blank?
117:
118: @implicit_readonly = true
119:
120: case join
121: when Hash, Array, Symbol
122: if array_of_strings?(join)
123: join_string = join.join(' ')
124: arel = arel.join(Arel::SqlLiteral.new(join_string))
125: end
126: when String
127: arel = arel.join(Arel::SqlLiteral.new(join))
128: else
129: arel = arel.join(join)
130: end
131: end
132: arel.joins(arel)
133: end
# File lib/active_record/relation/query_methods.rb, line 17
17: def eager_load(*args)
18: clone.tap {|r| r.eager_load_values += args if args.present? }
19: end
# File lib/active_record/relation/query_methods.rb, line 93
93: def extending(*modules, &block)
94: modules << Module.new(&block) if block_given?
95: clone.tap {|r| r.send(:apply_modules, *modules) }
96: end
# File lib/active_record/relation/query_methods.rb, line 89
89: def from(value = true)
90: clone.tap {|r| r.from_value = value }
91: end
# File lib/active_record/relation/query_methods.rb, line 33
33: def group(*args)
34: clone.tap {|r| r.group_values += args.flatten if args.present? }
35: end
# File lib/active_record/relation/query_methods.rb, line 57
57: def having(*args)
58: value = build_where(*args)
59: clone.tap {|r| r.having_values += Array.wrap(value) if value.present? }
60: end
# File lib/active_record/relation/query_methods.rb, line 12
12: def includes(*args)
13: args.reject! { |a| a.blank? }
14: clone.tap {|r| r.includes_values = (r.includes_values + args).flatten.uniq if args.present? }
15: end
# File lib/active_record/relation/query_methods.rb, line 45
45: def joins(*args)
46: args.flatten!
47: clone.tap {|r| r.joins_values += args if args.present? }
48: end
# File lib/active_record/relation/query_methods.rb, line 62
62: def limit(value = true)
63: copy = clone
64: copy.limit_value = value
65: copy
66: end
# File lib/active_record/relation/query_methods.rb, line 72
72: def lock(locks = true)
73: case locks
74: when String, TrueClass, NilClass
75: clone.tap {|r| r.lock_value = locks || true }
76: else
77: clone.tap {|r| r.lock_value = false }
78: end
79: end
# File lib/active_record/relation/query_methods.rb, line 68
68: def offset(value = true)
69: clone.tap {|r| r.offset_value = value }
70: end
# File lib/active_record/relation/query_methods.rb, line 37
37: def order(*args)
38: clone.tap {|r| r.order_values += args if args.present? }
39: end
# File lib/active_record/relation/query_methods.rb, line 21
21: def preload(*args)
22: clone.tap {|r| r.preload_values += args if args.present? }
23: end
# File lib/active_record/relation/query_methods.rb, line 81
81: def readonly(value = true)
82: clone.tap {|r| r.readonly_value = value }
83: end
# File lib/active_record/relation/query_methods.rb, line 41
41: def reorder(*args)
42: clone.tap {|r| r.order_values = args if args.present? }
43: end
# File lib/active_record/relation/query_methods.rb, line 98
98: def reverse_order
99: order_clause = arel.order_clauses.join(', ')
100: relation = except(:order)
101:
102: order = order_clause.blank? ?
103: "#{@klass.table_name}.#{@klass.primary_key} DESC" :
104: reverse_sql_order(order_clause)
105:
106: relation.order Arel::SqlLiteral.new order
107: end
# File lib/active_record/relation/query_methods.rb, line 238
238: def apply_modules(modules)
239: values = Array.wrap(modules)
240: @extensions += values if values.present?
241: values.each {|extension| extend(extension) }
242: end
# File lib/active_record/relation/query_methods.rb, line 256
256: def array_of_strings?(o)
257: o.is_a?(Array) && o.all?{|obj| obj.is_a?(String)}
258: end
# File lib/active_record/relation/query_methods.rb, line 181
181: def build_joins(relation, joins)
182: joined_associations = []
183: association_joins = []
184:
185: joins = @joins_values.map {|j| j.respond_to?(:strip) ? j.strip : j}.uniq
186:
187: joins.each do |join|
188: association_joins << join if [Hash, Array, Symbol].include?(join.class) && !array_of_strings?(join)
189: end
190:
191: stashed_association_joins = joins.grep(ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation)
192:
193: non_association_joins = (joins - association_joins - stashed_association_joins)
194: custom_joins = custom_join_sql(*non_association_joins)
195:
196: join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, association_joins, custom_joins)
197:
198: join_dependency.graft(*stashed_association_joins)
199:
200: @implicit_readonly = true unless association_joins.empty? && stashed_association_joins.empty?
201:
202: to_join = []
203:
204: join_dependency.join_associations.each do |association|
205: if (association_relation = association.relation).is_a?(Array)
206: to_join << [association_relation.first, association.join_class, association.association_join.first]
207: to_join << [association_relation.last, association.join_class, association.association_join.last]
208: else
209: to_join << [association_relation, association.join_class, association.association_join]
210: end
211: end
212:
213: to_join.each do |tj|
214: unless joined_associations.detect {|ja| ja[0] == tj[0] && ja[1] == tj[1] && ja[2] == tj[2] }
215: joined_associations << tj
216: relation = relation.join(tj[0], tj[1]).on(*tj[2])
217: end
218: end
219:
220: relation.join(custom_joins)
221: end
# File lib/active_record/relation/query_methods.rb, line 223
223: def build_select(arel, selects)
224: unless selects.empty?
225: @implicit_readonly = false
226: # TODO: fix this ugly hack, we should refactor the callers to get an ARel compatible array.
227: # Before this change we were passing to ARel the last element only, and ARel is capable of handling an array
228: if selects.all? {|s| s.is_a?(String) || !s.is_a?(Arel::Expression) } && !(selects.last =~ /^COUNT\(/)
229: arel.project(*selects)
230: else
231: arel.project(selects.last)
232: end
233: else
234: arel.project(Arel::SqlLiteral.new(@klass.quoted_table_name + '.*'))
235: end
236: end
# File lib/active_record/relation/query_methods.rb, line 244
244: def reverse_sql_order(order_query)
245: order_query.to_s.split(/,/).each { |s|
246: if s.match(/\s(asc|ASC)$/)
247: s.gsub!(/\s(asc|ASC)$/, ' DESC')
248: elsif s.match(/\s(desc|DESC)$/)
249: s.gsub!(/\s(desc|DESC)$/, ' ASC')
250: else
251: s.concat(' DESC')
252: end
253: }.join(',')
254: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.