Permalink
Browse files

Add Model.having and Relation#having

  • Loading branch information...
1 parent e8ca22d commit 91e28aae8649c503e81d66ad6829403ccc2c6571 @lifo lifo committed Dec 28, 2009
@@ -1,5 +1,9 @@
*Edge*
+* Add Model.having and Relation#having. [Pratik Naik]
+
+ Developer.group("salary").having("sum(salary) > 10000").select("salary")
+
* Add Relation#count. [Pratik Naik]
legends = People.where("age > 100")
@@ -1715,7 +1715,8 @@ def construct_finder_arel_with_included_associations(options, join_dependency)
relation = relation.joins(construct_join(options[:joins], scope)).
select(column_aliases(join_dependency)).
- group(construct_group(options[:group], options[:having], scope)).
+ group(options[:group] || (scope && scope[:group])).
+ having(options[:having] || (scope && scope[:having])).
order(construct_order(options[:order], scope)).
where(construct_conditions(options[:conditions], scope)).
from((scope && scope[:from]) || options[:from])
@@ -1759,7 +1760,8 @@ def construct_finder_sql_for_association_limiting(options, join_dependency)
relation = relation.joins(construct_join(options[:joins], scope)).
where(construct_conditions(options[:conditions], scope)).
- group(construct_group(options[:group], options[:having], scope)).
+ group(options[:group] || (scope && scope[:group])).
+ having(options[:having] || (scope && scope[:having])).
order(construct_order(options[:order], scope)).
limit(construct_limit(options[:limit], scope)).
offset(construct_limit(options[:offset], scope)).
@@ -21,7 +21,7 @@ def initialize(owner, reflection)
construct_sql
end
- delegate :group, :order, :limit, :joins, :where, :preload, :eager_load, :from, :lock, :readonly, :to => :scoped
+ delegate :group, :order, :limit, :joins, :where, :preload, :eager_load, :from, :lock, :readonly, :having, :to => :scoped
def select(select = nil, &block)
if block_given?
@@ -652,7 +652,7 @@ def find(*args)
end
end
- delegate :select, :group, :order, :limit, :joins, :where, :preload, :eager_load, :from, :lock, :readonly, :to => :scoped
+ delegate :select, :group, :order, :limit, :joins, :where, :preload, :eager_load, :from, :lock, :readonly, :having, :to => :scoped
# A convenience wrapper for <tt>find(:first, *args)</tt>. You can pass in all the
# same arguments to this method as you can to <tt>find(:first)</tt>.
@@ -1566,7 +1566,8 @@ def construct_finder_arel(options = {}, scope = scope(:find))
joins(construct_join(options[:joins], scope)).
where(construct_conditions(options[:conditions], scope)).
select(options[:select] || (scope && scope[:select]) || default_select(options[:joins] || (scope && scope[:joins]))).
- group(construct_group(options[:group], options[:having], scope)).
+ group(options[:group] || (scope && scope[:group])).
+ having(options[:having] || (scope && scope[:having])).
order(construct_order(options[:order], scope)).
limit(construct_limit(options[:limit], scope)).
offset(construct_offset(options[:offset], scope)).
@@ -1611,18 +1612,6 @@ def construct_join(joins, scope)
end
end
- def construct_group(group, having, scope)
- sql = ''
- if group
- sql << group.to_s
- sql << " HAVING #{sanitize_sql_for_conditions(having)}" if having
- elsif scope && (scoped_group = scope[:group])
- sql << scoped_group.to_s
- sql << " HAVING #{sanitize_sql_for_conditions(scope[:having])}" if scope[:having]
- end
- sql
- end
-
def construct_order(order, scope)
orders = []
@@ -194,7 +194,7 @@ def execute_grouped_calculation(operation, column_name, options, relation) #:nod
options[:select] << ", #{group_field} AS #{group_alias}"
- relation = relation.select(options[:select]).group(construct_group(options[:group], options[:having], nil))
+ relation = relation.select(options[:select]).group(options[:group]).having(options[:having])
calculated_data = connection.select_all(relation.to_sql)
@@ -55,6 +55,18 @@ def from(from)
from.present? ? create_new_relation(@relation.from(from)) : create_new_relation
end
+ def having(*args)
+ return create_new_relation if args.blank?
+
+ if [String, Hash, Array].include?(args.first.class)
+ havings = @klass.send(:merge_conditions, args.size > 1 ? Array.wrap(args) : args.first)
+ else
+ havings = args.first
+ end
+
+ create_new_relation(@relation.having(havings))
+ end
+
def group(groups)
groups.present? ? create_new_relation(@relation.group(groups)) : create_new_relation
end

0 comments on commit 91e28aa

Please sign in to comment.