Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #11693 from egilburg/minor_relation_refactor
Minor optimization and code cleanup in query_methods.rb
  • Loading branch information
rafaelfranca committed Aug 4, 2013
2 parents 7f7e16a + 1e583f8 commit 4fc74d2
Showing 1 changed file with 45 additions and 38 deletions.
83 changes: 45 additions & 38 deletions activerecord/lib/active_record/relation/query_methods.rb
Expand Up @@ -119,14 +119,15 @@ def create_with_value # :nodoc:
# #
# User.includes(:posts).where('posts.name = ?', 'example').references(:posts) # User.includes(:posts).where('posts.name = ?', 'example').references(:posts)
def includes(*args) def includes(*args)
check_if_method_has_arguments!("includes", args) check_if_method_has_arguments!(:includes, args)
spawn.includes!(*args) spawn.includes!(*args)
end end


def includes!(*args) # :nodoc: def includes!(*args) # :nodoc:
args.reject! {|a| a.blank? } args.reject!(&:blank?)
args.flatten!


self.includes_values = (includes_values + args).flatten.uniq self.includes_values |= args
self self
end end


Expand All @@ -137,7 +138,7 @@ def includes!(*args) # :nodoc:
# FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" = # FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" =
# "users"."id" # "users"."id"
def eager_load(*args) def eager_load(*args)
check_if_method_has_arguments!("eager_load", args) check_if_method_has_arguments!(:eager_load, args)
spawn.eager_load!(*args) spawn.eager_load!(*args)
end end


Expand All @@ -151,7 +152,7 @@ def eager_load!(*args) # :nodoc:
# User.preload(:posts) # User.preload(:posts)
# => SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN (1, 2, 3) # => SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN (1, 2, 3)
def preload(*args) def preload(*args)
check_if_method_has_arguments!("preload", args) check_if_method_has_arguments!(:preload, args)
spawn.preload!(*args) spawn.preload!(*args)
end end


Expand All @@ -169,14 +170,15 @@ def preload!(*args) # :nodoc:
# User.includes(:posts).where("posts.name = 'foo'").references(:posts) # User.includes(:posts).where("posts.name = 'foo'").references(:posts)
# # => Query now knows the string references posts, so adds a JOIN # # => Query now knows the string references posts, so adds a JOIN
def references(*args) def references(*args)
check_if_method_has_arguments!("references", args) check_if_method_has_arguments!(:references, args)
spawn.references!(*args) spawn.references!(*args)
end end


def references!(*args) # :nodoc: def references!(*args) # :nodoc:
args.flatten! args.flatten!
args.map!(&:to_s)


self.references_values = (references_values + args.map!(&:to_s)).uniq self.references_values |= args
self self
end end


Expand Down Expand Up @@ -229,7 +231,9 @@ def select(*fields)
end end


def select!(*fields) # :nodoc: def select!(*fields) # :nodoc:
self.select_values += fields.flatten fields.flatten!

self.select_values += fields
self self
end end


Expand All @@ -249,7 +253,7 @@ def select!(*fields) # :nodoc:
# User.group('name AS grouped_name, age') # User.group('name AS grouped_name, age')
# => [#<User id: 3, name: "Foo", age: 21, ...>, #<User id: 2, name: "Oscar", age: 21, ...>, #<User id: 5, name: "Foo", age: 23, ...>] # => [#<User id: 3, name: "Foo", age: 21, ...>, #<User id: 2, name: "Oscar", age: 21, ...>, #<User id: 5, name: "Foo", age: 23, ...>]
def group(*args) def group(*args)
check_if_method_has_arguments!("group", args) check_if_method_has_arguments!(:group, args)
spawn.group!(*args) spawn.group!(*args)
end end


Expand Down Expand Up @@ -280,24 +284,22 @@ def group!(*args) # :nodoc:
# User.order(:name, email: :desc) # User.order(:name, email: :desc)
# => SELECT "users".* FROM "users" ORDER BY "users"."name" ASC, "users"."email" DESC # => SELECT "users".* FROM "users" ORDER BY "users"."name" ASC, "users"."email" DESC
def order(*args) def order(*args)
check_if_method_has_arguments!("order", args) check_if_method_has_arguments!(:order, args)
spawn.order!(*args) spawn.order!(*args)
end end


def order!(*args) # :nodoc: def order!(*args) # :nodoc:
args.flatten! args.flatten!
validate_order_args args validate_order_args(args)


references = args.grep(String) references = args.grep(String)
references.map! { |arg| arg =~ /^([a-zA-Z]\w*)\.(\w+)/ && $1 }.compact! references.map! { |arg| arg =~ /^([a-zA-Z]\w*)\.(\w+)/ && $1 }.compact!
references!(references) if references.any? references!(references) if references.any?


# if a symbol is given we prepend the quoted table name # if a symbol is given we prepend the quoted table name
args.map! { |arg| args.map! do |arg|
arg.is_a?(Symbol) ? arg.is_a?(Symbol) ? Arel::Nodes::Ascending.new(klass.arel_table[arg]) : arg
Arel::Nodes::Ascending.new(klass.arel_table[arg]) : end
arg
}


self.order_values += args self.order_values += args
self self
Expand All @@ -313,13 +315,13 @@ def order!(*args) # :nodoc:
# #
# generates a query with 'ORDER BY id ASC, name ASC'. # generates a query with 'ORDER BY id ASC, name ASC'.
def reorder(*args) def reorder(*args)
check_if_method_has_arguments!("reorder", args) check_if_method_has_arguments!(:reorder, args)
spawn.reorder!(*args) spawn.reorder!(*args)
end end


def reorder!(*args) # :nodoc: def reorder!(*args) # :nodoc:
args.flatten! args.flatten!
validate_order_args args validate_order_args(args)


self.reordering_value = true self.reordering_value = true
self.order_values = args self.order_values = args
Expand Down Expand Up @@ -361,7 +363,7 @@ def reorder!(*args) # :nodoc:
# #
# will still have an order if it comes from the default_scope on Comment. # will still have an order if it comes from the default_scope on Comment.
def unscope(*args) def unscope(*args)
check_if_method_has_arguments!("unscope", args) check_if_method_has_arguments!(:unscope, args)
spawn.unscope!(*args) spawn.unscope!(*args)
end end


Expand Down Expand Up @@ -400,8 +402,12 @@ def unscope!(*args) # :nodoc:
# User.joins("LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id") # User.joins("LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id")
# => SELECT "users".* FROM "users" LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id # => SELECT "users".* FROM "users" LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id
def joins(*args) def joins(*args)
check_if_method_has_arguments!("joins", args) check_if_method_has_arguments!(:joins, args)
spawn.joins!(*args.compact.flatten)
args.compact!
args.flatten!

spawn.joins!(*args)
end end


def joins!(*args) # :nodoc: def joins!(*args) # :nodoc:
Expand Down Expand Up @@ -783,9 +789,10 @@ def extending(*modules, &block)
end end


def extending!(*modules, &block) # :nodoc: def extending!(*modules, &block) # :nodoc:
modules << Module.new(&block) if block_given? modules << Module.new(&block) if block
modules.flatten!


self.extending_values += modules.flatten self.extending_values += modules
extend(*extending_values) if extending_values.any? extend(*extending_values) if extending_values.any?


self self
Expand Down Expand Up @@ -816,12 +823,12 @@ def build_arel


collapse_wheres(arel, (where_values - ['']).uniq) collapse_wheres(arel, (where_values - ['']).uniq)


arel.having(*having_values.uniq.reject{|h| h.blank?}) unless having_values.empty? arel.having(*having_values.uniq.reject(&:blank?)) unless having_values.empty?


arel.take(connection.sanitize_limit(limit_value)) if limit_value arel.take(connection.sanitize_limit(limit_value)) if limit_value
arel.skip(offset_value.to_i) if offset_value arel.skip(offset_value.to_i) if offset_value


arel.group(*group_values.uniq.reject{|g| g.blank?}) unless group_values.empty? arel.group(*group_values.uniq.reject(&:blank?)) unless group_values.empty?


build_order(arel) build_order(arel)


Expand Down Expand Up @@ -870,11 +877,11 @@ def where_unscoping(target_value)
end end


def custom_join_ast(table, joins) def custom_join_ast(table, joins)
joins = joins.reject { |join| join.blank? } joins = joins.reject(&:blank?)


return [] if joins.empty? return [] if joins.empty?


joins.map do |join| joins.map! do |join|
case join case join
when Array when Array
join = Arel.sql(join.join(' ')) if array_of_strings?(join) join = Arel.sql(join.join(' ')) if array_of_strings?(join)
Expand All @@ -901,7 +908,7 @@ def build_where(opts, other = [])
when String, Array when String, Array
[@klass.send(:sanitize_sql, other.empty? ? opts : ([opts] + other))] [@klass.send(:sanitize_sql, other.empty? ? opts : ([opts] + other))]
when Hash when Hash
opts = PredicateBuilder.resolve_column_aliases klass, opts opts = PredicateBuilder.resolve_column_aliases(klass, opts)
attributes = @klass.send(:expand_hash_conditions_for_aggregates, opts) attributes = @klass.send(:expand_hash_conditions_for_aggregates, opts)


attributes.values.grep(ActiveRecord::Relation) do |rel| attributes.values.grep(ActiveRecord::Relation) do |rel|
Expand Down Expand Up @@ -944,7 +951,7 @@ def build_joins(manager, joins)
association_joins = buckets[:association_join] || [] association_joins = buckets[:association_join] || []
stashed_association_joins = buckets[:stashed_join] || [] stashed_association_joins = buckets[:stashed_join] || []
join_nodes = (buckets[:join_node] || []).uniq join_nodes = (buckets[:join_node] || []).uniq
string_joins = (buckets[:string_join] || []).map { |x| x.strip }.uniq string_joins = (buckets[:string_join] || []).map(&:strip).uniq


join_list = join_nodes + custom_join_ast(manager, string_joins) join_list = join_nodes + custom_join_ast(manager, string_joins)


Expand All @@ -956,13 +963,12 @@ def build_joins(manager, joins)


join_dependency.graft(*stashed_association_joins) join_dependency.graft(*stashed_association_joins)


joins = join_dependency.join_associations.map { |association| joins = join_dependency.join_associations.map!(&:join_constraints)
association.join_constraints joins.flatten!
}.flatten


joins.each { |join| manager.from join } joins.each { |join| manager.from(join) }


manager.join_sources.concat join_list manager.join_sources.concat(join_list)


manager manager
end end
Expand All @@ -983,7 +989,7 @@ def reverse_sql_order(order_query)
when Arel::Nodes::Ordering when Arel::Nodes::Ordering
o.reverse o.reverse
when String when String
o.to_s.split(',').collect do |s| o.to_s.split(',').map! do |s|
s.strip! s.strip!
s.gsub!(/\sasc\Z/i, ' DESC') || s.gsub!(/\sdesc\Z/i, ' ASC') || s.concat(' DESC') s.gsub!(/\sasc\Z/i, ' DESC') || s.gsub!(/\sdesc\Z/i, ' ASC') || s.concat(' DESC')
end end
Expand All @@ -1000,14 +1006,15 @@ def reverse_sql_order(order_query)
end end


def array_of_strings?(o) def array_of_strings?(o)
o.is_a?(Array) && o.all?{|obj| obj.is_a?(String)} o.is_a?(Array) && o.all? { |obj| obj.is_a?(String) }
end end


def build_order(arel) def build_order(arel)
orders = order_values orders = order_values.uniq
orders.reject!(&:blank?)
orders = reverse_sql_order(orders) if reverse_order_value orders = reverse_sql_order(orders) if reverse_order_value


orders = orders.uniq.reject(&:blank?).flat_map do |order| orders = orders.flat_map do |order|
case order case order
when Symbol when Symbol
table[order].asc table[order].asc
Expand Down

0 comments on commit 4fc74d2

Please sign in to comment.