aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib')
-rwxr-xr-xactiverecord/lib/active_record/associations.rb4
-rw-r--r--activerecord/lib/active_record/associations/has_many_association.rb18
2 files changed, 15 insertions, 7 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index b015699fba..b83ce831c7 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -166,6 +166,8 @@ module ActiveRecord
# May not be set if :dependent is also set.
# * <tt>:finder_sql</tt> - specify a complete SQL statement to fetch the association. This is a good way to go for complex
# associations that depends on multiple tables. Note: When this option is used, +find_in_collection+ is _not_ added.
+ # * <tt>:counter_sql</tt> - specify a complete SQL statement to fetch the size of the association. If +:finder_sql+ is
+ # specified but +:counter_sql+, +:counter_sql+ will be generated by replacing SELECT ... FROM with SELECT COUNT(*) FROM.
#
# Option examples:
# has_many :comments, :order => "posted_on"
@@ -177,7 +179,7 @@ module ActiveRecord
# 'WHERE ps.post_id = #{id} AND ps.person_id = p.id ' +
# 'ORDER BY p.first_name'
def has_many(association_id, options = {})
- validate_options([ :foreign_key, :class_name, :exclusively_dependent, :dependent, :conditions, :order, :finder_sql ], options.keys)
+ validate_options([ :foreign_key, :class_name, :exclusively_dependent, :dependent, :conditions, :order, :finder_sql, :counter_sql ], options.keys)
association_name, association_class_name, association_class_primary_key_name =
associate_identification(association_id, options[:class_name], options[:foreign_key])
diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb
index 947862ad37..0f2d20d240 100644
--- a/activerecord/lib/active_record/associations/has_many_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_association.rb
@@ -7,9 +7,15 @@ module ActiveRecord
if options[:finder_sql]
@finder_sql = interpolate_sql(options[:finder_sql])
- @counter_sql = @finder_sql.gsub(/SELECT (.*) FROM/i, "SELECT COUNT(*) FROM")
else
- @finder_sql = "#{@association_class_primary_key_name} = '#{@owner.id}' #{@conditions ? " AND " + interpolate_sql(@conditions) : ""}"
+ @finder_sql = "#{@association_class_primary_key_name} = '#{@owner.id}' #{@conditions ? " AND " + interpolate_sql(@conditions) : ""}"
+ end
+
+ if options[:counter_sql]
+ @counter_sql = interpolate_sql(options[:counter_sql])
+ elsif options[:finder_sql]
+ @counter_sql = options[:counter_sql] = @finder_sql.gsub(/SELECT (.*) FROM/i, "SELECT COUNT(*) FROM")
+ else
@counter_sql = "#{@association_class_primary_key_name} = '#{@owner.id}'#{@conditions ? " AND " + interpolate_sql(@conditions) : ""}"
end
end
@@ -70,21 +76,21 @@ module ActiveRecord
@association_class.find_all(@finder_sql, @options[:order] ? @options[:order] : nil)
end
end
-
+
def count_records
if has_cached_counter?
@owner.send(:read_attribute, cached_counter_attribute_name)
- elsif @options[:finder_sql]
+ elsif @options[:counter_sql]
@association_class.count_by_sql(@counter_sql)
else
@association_class.count(@counter_sql)
end
end
-
+
def has_cached_counter?
@owner.attribute_present?(cached_counter_attribute_name)
end
-
+
def cached_counter_attribute_name
"#{@association_name}_count"
end