Permalink
Browse files

New group scoped #blank? and #present? which simply checks if the pro…

…xy owner has a group set.

This allows us to tune the SQL generated to IN statements only when needed, even if a grouped
scope is being used.
  • Loading branch information...
1 parent 2bdfe3b commit 50578c436a64deec22a685589039a5254f70e769 @metaskills committed Dec 6, 2011
View
@@ -7,6 +7,10 @@
* The group object is now an ActiveRecord::Relation so you can further scope it.
+* New group scoped #blank? and #present? which simply checks if the proxy owner has a group set.
+ This allows us to tune the SQL generated to IN statements only when needed, even if a grouped
+ scope is being used.
+
* New group.ids_sql which is an Arel SQL literal. Avoids large groups IDs and better query plans.
@@ -48,7 +48,11 @@ def add_constraints(scope)
if reflection == chain.last
# GroupedScope changed this line.
# scope = scope.where(table[key].eq(owner[foreign_key]))
- scope = scope.where(table[key].in(owner.group.ids))
+ scope = if owner.group.present?
+ scope.where(table[key].in(owner.group.ids))
+ else
+ scope.where(table[key].eq(owner[foreign_key]))
+ end
if reflection.type
scope = scope.where(table[reflection.type].eq(owner.class.base_class.name))
@@ -17,6 +17,14 @@ def initialize(proxy_owner)
@proxy_owner = proxy_owner
end
+ def blank?
+ proxy_owner.group_id.blank?
+ end
+
+ def present?
+ !blank?
+ end
+
def ids
grouped_scoped_ids.map(&primary_key.to_sym)
end
@@ -64,17 +72,13 @@ def grouped_proxy
@grouped_proxy ||= grouped_scoped
end
- def grouped?
- proxy_owner.group_id.present?
- end
-
def all_grouped?
proxy_owner.all_grouped? rescue false
end
def grouped_scoped
return proxy_class.scoped if all_grouped?
- proxy_class.where grouped? ? arel_group_id.eq(proxy_owner.group_id) : arel_primary_key.eq(proxy_owner.id)
+ proxy_class.where present? ? arel_group_id.eq(proxy_owner.group_id) : arel_primary_key.eq(proxy_owner.id)
end
def grouped_scoped_ids
@@ -8,13 +8,20 @@ class GroupedScope::HasManyTest < GroupedScope::TestCase
@employee = FactoryGirl.create(:employee)
end
- it 'scope existing association to owner' do
+ it 'scopes existing association to owner' do
assert_sql(/"employee_id" = #{@employee.id}/) do
@employee.reports(true)
end
end
- it 'scope group association to group' do
+ it 'scopes group association to owner when no group present' do
+ assert_sql(/"employee_id" = #{@employee.id}/) do
+ @employee.group.reports(true)
+ end
+ end
+
+ it 'scopes group association to owner when group present' do
+ @employee.update_attribute :group_id, 43
assert_sql(/"employee_id" IN \(#{@employee.id}\)/) do
@employee.group.reports(true)
end
@@ -110,7 +117,14 @@ class GroupedScope::HasManyTest < GroupedScope::TestCase
end
end
- it 'scope group association to group' do
+ it 'scope group association to owner, since no group is present' do
+ assert_sql(/"legacy_reports"."email" = '#{@employee.id}'/) do
+ @employee.group.reports(true)
+ end
+ end
+
+ it 'scopes group association to owners group when present' do
+ @employee.update_attribute :group_id, 43
assert_sql(/"legacy_reports"."email" IN \('#{@employee.id}'\)/) do
@employee.group.reports(true)
end
@@ -34,6 +34,21 @@ class GroupedScope::SelfGrouppingTest < GroupedScope::TestCase
end
end
+ it 'allows you to ask if the group is present' do
+ @employee.update_attribute :group_id, 28
+ assert_no_queries do
+ assert @employee.group_id.present?
+ assert @employee.group.present?
+ end
+ end
+
+ it 'allows you to ask if the group is blank' do
+ assert_no_queries do
+ assert @employee.group_id.blank?
+ assert @employee.group.blank?
+ end
+ end
+
describe 'for #with_reflection' do
before { @reflection = Employee.reflections[:reports] }

0 comments on commit 50578c4

Please sign in to comment.