Skip to content

Commit

Permalink
New group scoped #blank? and #present? which simply checks if the pro…
Browse files Browse the repository at this point in the history
…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
metaskills committed Dec 6, 2011
1 parent 2bdfe3b commit 50578c4
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 9 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -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.


Expand Down
6 changes: 5 additions & 1 deletion lib/grouped_scope/arish/associations/association_scope.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
14 changes: 9 additions & 5 deletions lib/grouped_scope/self_grouping.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
20 changes: 17 additions & 3 deletions test/grouped_scope/has_many_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
15 changes: 15 additions & 0 deletions test/grouped_scope/self_grouping_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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] }
Expand Down

0 comments on commit 50578c4

Please sign in to comment.