aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/CHANGELOG4
-rwxr-xr-xactiverecord/lib/active_record/associations.rb6
-rw-r--r--activerecord/lib/active_record/associations/association_collection.rb2
-rwxr-xr-xactiverecord/lib/active_record/base.rb17
-rw-r--r--activerecord/lib/active_record/calculations.rb2
-rw-r--r--activerecord/lib/active_record/relation.rb12
6 files changed, 25 insertions, 18 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index 5af66c3519..28ae2262e2 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -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")
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index c23c9f63f1..7242ebf387 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1715,7 +1715,8 @@ module ActiveRecord
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 @@ module ActiveRecord
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)).
diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb
index 8bc64a3a93..56b2a90138 100644
--- a/activerecord/lib/active_record/associations/association_collection.rb
+++ b/activerecord/lib/active_record/associations/association_collection.rb
@@ -21,7 +21,7 @@ module ActiveRecord
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?
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 3135234706..767109474d 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -652,7 +652,7 @@ module ActiveRecord #:nodoc:
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 @@ module ActiveRecord #:nodoc:
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 @@ module ActiveRecord #:nodoc:
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 = []
diff --git a/activerecord/lib/active_record/calculations.rb b/activerecord/lib/active_record/calculations.rb
index fcba23dc0d..59811c40a8 100644
--- a/activerecord/lib/active_record/calculations.rb
+++ b/activerecord/lib/active_record/calculations.rb
@@ -194,7 +194,7 @@ module ActiveRecord
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)
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index 291e97ff83..c7a74b7763 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -55,6 +55,18 @@ module ActiveRecord
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