grouped_scope 0.6.1 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +5 -0
- data/CHANGELOG +13 -0
- data/Gemfile +4 -6
- data/README.md +173 -0
- data/lib/grouped_scope.rb +7 -7
- data/lib/grouped_scope/arish/associations/association_scope.rb +90 -0
- data/lib/grouped_scope/arish/associations/builder/grouped_association.rb +50 -0
- data/lib/grouped_scope/arish/associations/builder/grouped_collection_association.rb +32 -0
- data/lib/grouped_scope/arish/associations/collection_association.rb +25 -0
- data/lib/grouped_scope/arish/base.rb +24 -0
- data/lib/grouped_scope/arish/reflection.rb +18 -0
- data/lib/grouped_scope/arish/relation/predicate_builer.rb +27 -0
- data/lib/grouped_scope/errors.rb +2 -3
- data/lib/grouped_scope/self_grouping.rb +59 -23
- data/lib/grouped_scope/version.rb +2 -4
- data/test/cases/has_many_test.rb +155 -0
- data/test/cases/has_many_through_test.rb +51 -0
- data/test/cases/reflection_test.rb +62 -0
- data/test/cases/self_grouping_test.rb +201 -0
- data/test/helper.rb +48 -35
- metadata +27 -30
- data/README.rdoc +0 -98
- data/lib/grouped_scope/association_reflection.rb +0 -54
- data/lib/grouped_scope/class_methods.rb +0 -32
- data/lib/grouped_scope/core_ext.rb +0 -29
- data/lib/grouped_scope/grouping.rb +0 -9
- data/lib/grouped_scope/has_many_association.rb +0 -28
- data/lib/grouped_scope/has_many_through_association.rb +0 -28
- data/lib/grouped_scope/instance_methods.rb +0 -10
- data/test/grouped_scope/association_reflection_test.rb +0 -73
- data/test/grouped_scope/class_methods_test.rb +0 -51
- data/test/grouped_scope/has_many_association_test.rb +0 -156
- data/test/grouped_scope/has_many_through_association_test.rb +0 -51
- data/test/grouped_scope/self_grouping_test.rb +0 -146
data/README.rdoc
DELETED
@@ -1,98 +0,0 @@
|
|
1
|
-
|
2
|
-
== GroupedScope: Has Many Associations IN (GROUPS)
|
3
|
-
|
4
|
-
GroupedScope aims to make two things easier in your ActiveRecord models. First, provide a
|
5
|
-
easy way to group objects, second, to allow the group to share associated object via existing
|
6
|
-
has_many relationships. See installation and usage for more details.
|
7
|
-
|
8
|
-
By the way, this plugin has been tested with rails 2.3.2, 2.2.2, and 2.1.1
|
9
|
-
|
10
|
-
|
11
|
-
=== Installation & Usage
|
12
|
-
|
13
|
-
From your project's RAILS_ROOT, run:
|
14
|
-
|
15
|
-
./script/plugin install git://github.com/metaskills/grouped_scope.git
|
16
|
-
|
17
|
-
To use GroupedScope on a model it must have a :group_id column.
|
18
|
-
|
19
|
-
class AddGroupId < ActiveRecord::Migration
|
20
|
-
def self.up
|
21
|
-
add_column :employees, :group_id, :integer
|
22
|
-
end
|
23
|
-
def self.down
|
24
|
-
remove_column :employees, :group_id
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
Assume the following model.
|
29
|
-
|
30
|
-
class Employee < ActiveRecord::Base
|
31
|
-
has_many :reports
|
32
|
-
grouped_scope :reports
|
33
|
-
end
|
34
|
-
|
35
|
-
By calling grouped_scope on any association you create a new group accessor for each
|
36
|
-
instance. The object returned will act just like an array and at least include the
|
37
|
-
current object that called it.
|
38
|
-
|
39
|
-
@employee_one.group # => [#<Employee id: 1, group_id: nil>]
|
40
|
-
|
41
|
-
To group resources, just assign the same :group_id in the schema. Note that in future
|
42
|
-
versions I will be extending the GroupedScope::Grouping that each object belongs to.
|
43
|
-
If you do not just want to assign some random integers, then take a look at that model
|
44
|
-
and the belongs_to :grouping code, schema needed ofcourse
|
45
|
-
|
46
|
-
@employee_one.update_attribute :group_id, 1
|
47
|
-
@employee_two.update_attribute :group_id, 1
|
48
|
-
@employee_one.group # => [#<Employee id: 1, group_id: 1>, #<Employee id: 2, group_id: 1>]
|
49
|
-
|
50
|
-
Calling grouped_scope on the :reports association leaves the existing association intact.
|
51
|
-
|
52
|
-
@employee_one.reports # => [#<Report id: 2, employee_id: 1>]
|
53
|
-
@employee_two.reports # => [#<Report id: 18, employee_id: 2>, #<Report id: 36, employee_id: 2>]
|
54
|
-
|
55
|
-
Now the good part, all associations passed to the grouped_scope method can be called
|
56
|
-
on the group proxy. The collection will return resources shared by the group.
|
57
|
-
|
58
|
-
@employee_one.group.reports # => [#<Report id: 2, employee_id: 1>,
|
59
|
-
#<Report id: 18, employee_id: 2>,
|
60
|
-
#<Report id: 36, employee_id: 2>]
|
61
|
-
|
62
|
-
You can even call named scopes defined on the objects in the collection and association
|
63
|
-
extensions defined on the original has_many. For instance:
|
64
|
-
|
65
|
-
@employee.group.reports.urgent.assigned_to(user)
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
=== Todo List
|
70
|
-
|
71
|
-
* Go back and start adding some rdocs.
|
72
|
-
* Add more GroupedScope::Grouping code.
|
73
|
-
* Add polymorphic support.
|
74
|
-
* Add/test has_and_belongs_to_many
|
75
|
-
* Raise errors and/or support :finder_sql/:counter_sql.
|
76
|
-
* Add a user definable group_id schema.
|
77
|
-
|
78
|
-
|
79
|
-
=== Helping Our & Running Tests
|
80
|
-
|
81
|
-
Running the test suite is easy to do. Just make sure you have the following gems installed.
|
82
|
-
|
83
|
-
* shoulda
|
84
|
-
* quitebacktrace
|
85
|
-
* mocha
|
86
|
-
* factory_girl
|
87
|
-
|
88
|
-
If you want to run the tests for a specific version of rails in gems (other than the latest),
|
89
|
-
then you can set the RAILS_VERSION environment variable. For example `env RAILS_VERSION=1.2.6 autotest`.
|
90
|
-
When doing this you also need to make sure that you download version 4.1 of shoulda (not the gem)
|
91
|
-
and place its lib contents into `test/lib/shoulda` and `test/lib/shoulda.rb`. The reason is that
|
92
|
-
the latest should gem require ActiveSupport greater than 2.0.
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
Copyright (c) 2008 Ken Collins, Decisiv Inc.
|
97
|
-
Released under the MIT license.
|
98
|
-
|
@@ -1,54 +0,0 @@
|
|
1
|
-
module GroupedScope
|
2
|
-
class AssociationReflection < ActiveRecord::Reflection::AssociationReflection
|
3
|
-
|
4
|
-
((ActiveRecord::Reflection::AssociationReflection.instance_methods-Class.instance_methods) +
|
5
|
-
(ActiveRecord::Reflection::AssociationReflection.private_instance_methods-Class.private_instance_methods)).each do |m|
|
6
|
-
undef_method(m)
|
7
|
-
end
|
8
|
-
|
9
|
-
attr_accessor :name, :options
|
10
|
-
|
11
|
-
def initialize(active_record,ungrouped_name)
|
12
|
-
@active_record = active_record
|
13
|
-
@ungrouped_name = ungrouped_name
|
14
|
-
@name = :"grouped_scope_#{@ungrouped_name}"
|
15
|
-
verify_ungrouped_reflection
|
16
|
-
super(ungrouped_reflection.macro, @name, ungrouped_reflection.options.dup, @active_record)
|
17
|
-
create_grouped_association
|
18
|
-
end
|
19
|
-
|
20
|
-
def ungrouped_reflection
|
21
|
-
@active_record.reflections[@ungrouped_name]
|
22
|
-
end
|
23
|
-
|
24
|
-
def respond_to?(method, include_private=false)
|
25
|
-
super || ungrouped_reflection.respond_to?(method,include_private)
|
26
|
-
end
|
27
|
-
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def method_missing(method, *args, &block)
|
32
|
-
ungrouped_reflection.send(method, *args, &block)
|
33
|
-
end
|
34
|
-
|
35
|
-
def verify_ungrouped_reflection
|
36
|
-
if ungrouped_reflection.blank? || ungrouped_reflection.macro.to_s !~ /has_many|has_and_belongs_to_many/
|
37
|
-
raise ArgumentError, "Cannot create a group scope for :#{@ungrouped_name} because it is not a has_many " +
|
38
|
-
"or a has_and_belongs_to_many association. Make sure to call grouped_scope after " +
|
39
|
-
"the has_many associations."
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def create_grouped_association
|
44
|
-
active_record.send(macro, name, options)
|
45
|
-
association_proxy_class = options[:through] ? ActiveRecord::Associations::HasManyThroughAssociation : ActiveRecord::Associations::HasManyAssociation
|
46
|
-
active_record.send(:collection_reader_method, self, association_proxy_class)
|
47
|
-
|
48
|
-
active_record.reflections[name] = self
|
49
|
-
active_record.grouped_scopes[@ungrouped_name] = true
|
50
|
-
options[:grouped_scope] = true
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
54
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
module GroupedScope
|
2
|
-
module ClassMethods
|
3
|
-
|
4
|
-
def grouped_scopes
|
5
|
-
read_inheritable_attribute(:grouped_scopes) || write_inheritable_attribute(:grouped_scopes, {})
|
6
|
-
end
|
7
|
-
|
8
|
-
def grouped_scope(*associations)
|
9
|
-
create_belongs_to_for_grouped_scope
|
10
|
-
associations.each { |association| AssociationReflection.new(self,association) }
|
11
|
-
create_grouped_scope_accessor
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def create_grouped_scope_accessor
|
17
|
-
define_method(:group) do
|
18
|
-
@group ||= SelfGroupping.new(self)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def create_belongs_to_for_grouped_scope
|
23
|
-
grouping_class_name = 'GroupedScope::Grouping'
|
24
|
-
existing_grouping = reflections[:grouping]
|
25
|
-
return false if existing_grouping && existing_grouping.macro == :belongs_to && existing_grouping.options[:class_name] == grouping_class_name
|
26
|
-
belongs_to :grouping, :foreign_key => 'group_id', :class_name => grouping_class_name
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
ActiveRecord::Base.send :extend, GroupedScope::ClassMethods
|
@@ -1,29 +0,0 @@
|
|
1
|
-
|
2
|
-
class ActiveRecord::Base
|
3
|
-
|
4
|
-
class << self
|
5
|
-
|
6
|
-
private
|
7
|
-
|
8
|
-
def attribute_condition_with_grouped_scope(*args)
|
9
|
-
if ActiveRecord::VERSION::STRING >= '2.3.0'
|
10
|
-
quoted_column_name, argument = args
|
11
|
-
case argument
|
12
|
-
when GroupedScope::SelfGroupping then "#{quoted_column_name} IN (?)"
|
13
|
-
else attribute_condition_without_grouped_scope(quoted_column_name,argument)
|
14
|
-
end
|
15
|
-
else
|
16
|
-
argument = args.first
|
17
|
-
case argument
|
18
|
-
when GroupedScope::SelfGroupping then "IN (?)"
|
19
|
-
else attribute_condition_without_grouped_scope(argument)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
alias_method_chain :attribute_condition, :grouped_scope
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module GroupedScope
|
2
|
-
module HasManyAssociation
|
3
|
-
|
4
|
-
def self.included(klass)
|
5
|
-
klass.class_eval do
|
6
|
-
alias_method_chain :construct_sql, :group_scope
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
def construct_sql_with_group_scope
|
11
|
-
if @reflection.options[:grouped_scope]
|
12
|
-
if @reflection.options[:as]
|
13
|
-
# TODO: Need to add case for polymorphic :as option.
|
14
|
-
else
|
15
|
-
@finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} IN (#{@owner.group.quoted_ids})"
|
16
|
-
@finder_sql << " AND (#{conditions})" if conditions
|
17
|
-
end
|
18
|
-
@counter_sql = @finder_sql
|
19
|
-
else
|
20
|
-
construct_sql_without_group_scope
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
ActiveRecord::Associations::HasManyAssociation.send :include, GroupedScope::HasManyAssociation
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module GroupedScope
|
2
|
-
module HasManyThroughAssociation
|
3
|
-
|
4
|
-
def self.included(klass)
|
5
|
-
klass.class_eval do
|
6
|
-
alias_method_chain :construct_conditions, :group_scope
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
def construct_conditions_with_group_scope
|
11
|
-
conditions = construct_conditions_without_group_scope
|
12
|
-
if @reflection.options[:grouped_scope]
|
13
|
-
if as = @reflection.options[:as]
|
14
|
-
# TODO: Need to add case for polymorphic :as option.
|
15
|
-
else
|
16
|
-
pattern = "#{@reflection.primary_key_name} = #{@owner.quoted_id}"
|
17
|
-
replacement = "#{@reflection.primary_key_name} IN (#{@owner.group.quoted_ids})"
|
18
|
-
conditions.sub!(pattern,replacement)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
conditions
|
22
|
-
end
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
ActiveRecord::Associations::HasManyThroughAssociation.send :include, GroupedScope::HasManyThroughAssociation
|
@@ -1,73 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class GroupedScope::AssociationReflectionTest < GroupedScope::TestCase
|
4
|
-
|
5
|
-
setup do
|
6
|
-
setup_environment
|
7
|
-
end
|
8
|
-
|
9
|
-
context 'For initialization' do
|
10
|
-
|
11
|
-
context 'Raise and exception' do
|
12
|
-
|
13
|
-
setup { @reflection_klass = GroupedScope::AssociationReflection }
|
14
|
-
|
15
|
-
should 'when a association does not exist' do
|
16
|
-
lambda{ @reflection_klass.new(Employee,:doesnotexist) }.must_raise(ArgumentError)
|
17
|
-
end
|
18
|
-
|
19
|
-
should 'when the association is not a has_many or a has_and_belongs_to_many' do
|
20
|
-
Employee.class_eval { belongs_to(:foo) }
|
21
|
-
lambda{ @reflection_klass.new(Employee,:foo) }.must_raise(ArgumentError)
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
context 'For #ungrouped_reflection' do
|
29
|
-
|
30
|
-
setup do
|
31
|
-
@ungrouped_reflection = Employee.reflections[:reports]
|
32
|
-
@grouped_reflection = Employee.reflections[:grouped_scope_reports]
|
33
|
-
end
|
34
|
-
|
35
|
-
should 'access ungrouped reflection' do
|
36
|
-
assert_equal @ungrouped_reflection, @grouped_reflection.ungrouped_reflection
|
37
|
-
end
|
38
|
-
|
39
|
-
should 'delegate instance methods to #ungrouped_reflection' do
|
40
|
-
methods = [:class_name,:klass,:table_name,:primary_key_name,:active_record,
|
41
|
-
:association_foreign_key,:counter_cache_column,:source_reflection]
|
42
|
-
methods.each do |m|
|
43
|
-
assert_equal @ungrouped_reflection.send(m), @grouped_reflection.send(m),
|
44
|
-
"The method #{m.inspect} does not appear to be proxied to the ungrouped reflection."
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
should 'not delegate to #ungrouped_reflection for #options and #name' do
|
49
|
-
@ungrouped_reflection.name.wont_equal @grouped_reflection.name
|
50
|
-
@ungrouped_reflection.options.wont_equal @grouped_reflection.options
|
51
|
-
end
|
52
|
-
|
53
|
-
should 'derive class name to same as ungrouped reflection' do
|
54
|
-
assert_equal @ungrouped_reflection.send(:derive_class_name), @grouped_reflection.send(:derive_class_name)
|
55
|
-
end
|
56
|
-
|
57
|
-
should 'derive primary key name to same as ungrouped reflection' do
|
58
|
-
assert_equal @ungrouped_reflection.send(:derive_primary_key_name), @grouped_reflection.send(:derive_primary_key_name)
|
59
|
-
end
|
60
|
-
|
61
|
-
should 'honor explicit legacy reports association options like class_name and foreign_key' do
|
62
|
-
@ungrouped_reflection = LegacyEmployee.reflections[:reports]
|
63
|
-
@grouped_reflection = LegacyEmployee.reflections[:grouped_scope_reports]
|
64
|
-
[:class_name,:primary_key_name].each do |m|
|
65
|
-
assert_equal @ungrouped_reflection.send(m), @grouped_reflection.send(m),
|
66
|
-
"The method #{m.inspect} does not appear to be proxied to the ungrouped reflection."
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
end
|
71
|
-
|
72
|
-
|
73
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class GroupedScope::ClassMethodsTest < GroupedScope::TestCase
|
4
|
-
|
5
|
-
setup do
|
6
|
-
setup_environment
|
7
|
-
end
|
8
|
-
|
9
|
-
context 'For .grouped_scopes' do
|
10
|
-
|
11
|
-
should 'have a inheritable attribute hash' do
|
12
|
-
assert_instance_of Hash, Employee.grouped_scopes
|
13
|
-
end
|
14
|
-
|
15
|
-
should 'add to inheritable attributes with new grouped_scope' do
|
16
|
-
Employee.grouped_scopes[:foobars] = nil
|
17
|
-
Employee.class_eval { has_many(:foobars) ; grouped_scope(:foobars) }
|
18
|
-
assert Employee.grouped_scopes[:foobars]
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
context 'For .grouped_scope' do
|
24
|
-
|
25
|
-
should 'create a belongs_to :grouping association' do
|
26
|
-
assert Employee.reflections[:grouping]
|
27
|
-
end
|
28
|
-
|
29
|
-
should 'not recreate belongs_to :grouping on additional calls' do
|
30
|
-
Employee.stubs(:belongs_to).never
|
31
|
-
Employee.class_eval { has_many(:foobars) ; grouped_scope(:foobars) }
|
32
|
-
end
|
33
|
-
|
34
|
-
should 'create a has_many assoc named :grouped_scope_* using existing association as a suffix' do
|
35
|
-
grouped_reports_assoc = Employee.reflections[:grouped_scope_reports]
|
36
|
-
assert_instance_of GroupedScope::AssociationReflection, grouped_reports_assoc
|
37
|
-
assert FactoryGirl.create(:employee).respond_to?(:grouped_scope_reports)
|
38
|
-
end
|
39
|
-
|
40
|
-
should 'not add the :grouped_scope option to existing reflection' do
|
41
|
-
assert_nil Employee.reflections[:reports].options[:grouped_scope]
|
42
|
-
end
|
43
|
-
|
44
|
-
should 'have added the :grouped_scope option to new grouped reflection' do
|
45
|
-
assert Employee.reflections[:grouped_scope_reports].options[:grouped_scope]
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
|
51
|
-
end
|
@@ -1,156 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class GroupedScope::HasManyAssociationTest < GroupedScope::TestCase
|
4
|
-
|
5
|
-
setup do
|
6
|
-
setup_environment
|
7
|
-
end
|
8
|
-
|
9
|
-
context 'For an Employee' do
|
10
|
-
|
11
|
-
setup do
|
12
|
-
@employee = FactoryGirl.create(:employee)
|
13
|
-
end
|
14
|
-
|
15
|
-
should 'scope existing association to owner' do
|
16
|
-
assert_sql(/employee_id = #{@employee.id}/) do
|
17
|
-
@employee.reports(true)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
should 'scope group association to group' do
|
22
|
-
assert_sql(/employee_id IN \(#{@employee.id}\)/) do
|
23
|
-
@employee.group.reports(true)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
context 'for counting sql' do
|
28
|
-
|
29
|
-
setup do
|
30
|
-
@e1 = FactoryGirl.create(:employee_with_reports, :group_id => 1)
|
31
|
-
@e2 = FactoryGirl.create(:employee_with_reports, :group_id => 1)
|
32
|
-
end
|
33
|
-
|
34
|
-
should 'scope count sql to owner' do
|
35
|
-
assert_sql(/SELECT count\(\*\)/,/employee_id = #{@e1.id}/) do
|
36
|
-
@e1.reports(true).count
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
should 'scope count sql to group' do
|
41
|
-
assert_sql(/SELECT count\(\*\)/,/employee_id IN \(#{@e1.id},#{@e2.id}\)/) do
|
42
|
-
@e1.group.reports(true).count
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
should 'have a group count equal to sum of seperate owner counts' do
|
47
|
-
assert_equal @e1.reports(true).count + @e2.reports(true).count, @e2.group.reports(true).count
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
51
|
-
|
52
|
-
context 'training association extensions' do
|
53
|
-
|
54
|
-
setup do
|
55
|
-
@e1 = FactoryGirl.create(:employee_with_urgent_reports, :group_id => 1)
|
56
|
-
@e2 = FactoryGirl.create(:employee, :group_id => 1)
|
57
|
-
@urgent_reports = @e1.reports.select(&:urgent_title?)
|
58
|
-
end
|
59
|
-
|
60
|
-
should 'find urgent report via normal ungrouped association' do
|
61
|
-
assert_same_elements @urgent_reports, @e1.reports(true).urgent
|
62
|
-
end
|
63
|
-
|
64
|
-
should 'find urgent report via grouped reflection' do
|
65
|
-
assert_same_elements @urgent_reports, @e2.group.reports(true).urgent
|
66
|
-
end
|
67
|
-
|
68
|
-
should 'use assoc extension SQL along with group reflection' do
|
69
|
-
assert_sql(select_from_reports, where_for_groups, where_for_urgent_title) do
|
70
|
-
@e2.group.reports.urgent
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
end
|
75
|
-
|
76
|
-
context 'training named scopes' do
|
77
|
-
|
78
|
-
setup do
|
79
|
-
@e1 = FactoryGirl.create(:employee_with_urgent_reports, :group_id => 1)
|
80
|
-
@e2 = FactoryGirl.create(:employee, :group_id => 1)
|
81
|
-
@urgent_titles = @e1.reports.select(&:urgent_title?)
|
82
|
-
@urgent_bodys = @e1.reports.select(&:urgent_body?)
|
83
|
-
end
|
84
|
-
|
85
|
-
should 'find urgent reports via normal named scopes by normal owner' do
|
86
|
-
assert_same_elements @urgent_titles, @e1.reports(true).with_urgent_title
|
87
|
-
assert_same_elements @urgent_bodys, @e1.reports(true).with_urgent_body
|
88
|
-
end
|
89
|
-
|
90
|
-
should 'find urgent reports via group reflection by group member' do
|
91
|
-
assert_same_elements @urgent_titles, @e2.group.reports(true).with_urgent_title
|
92
|
-
assert_same_elements @urgent_bodys, @e2.group.reports(true).with_urgent_body
|
93
|
-
end
|
94
|
-
|
95
|
-
should 'use named scope SQL along with group reflection' do
|
96
|
-
assert_sql(select_from_reports, where_for_groups, where_for_urgent_body, where_for_urgent_title) do
|
97
|
-
@e2.group.reports.with_urgent_title.with_urgent_body.inspect
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
context 'with will paginate' do
|
102
|
-
|
103
|
-
should 'use group reflection, named scope, and paginate SQL' do
|
104
|
-
where_ends_with_limits = /WHERE.*LIMIT 2 OFFSET 0/
|
105
|
-
assert_sql(select_from_reports, where_for_groups, where_for_urgent_body, where_for_urgent_title, where_ends_with_limits) do
|
106
|
-
@e2.group.reports.with_urgent_title.with_urgent_body.paginate(:page=>1,:per_page=>2)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
111
|
-
|
112
|
-
end
|
113
|
-
|
114
|
-
end
|
115
|
-
|
116
|
-
context 'For a LegacyEmployee' do
|
117
|
-
|
118
|
-
setup do
|
119
|
-
@employee = FactoryGirl.create(:legacy_employee)
|
120
|
-
end
|
121
|
-
|
122
|
-
should 'scope existing association to owner' do
|
123
|
-
assert_sql(/"?legacy_reports"?.email = '#{@employee.id}'/) do
|
124
|
-
@employee.reports(true)
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
should 'scope group association to group' do
|
129
|
-
assert_sql(/"?legacy_reports"?.email IN \('#{@employee.id}'\)/) do
|
130
|
-
@employee.group.reports(true)
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
end
|
135
|
-
|
136
|
-
|
137
|
-
protected
|
138
|
-
|
139
|
-
def select_from_reports
|
140
|
-
/SELECT \* FROM "?reports"?/
|
141
|
-
end
|
142
|
-
|
143
|
-
def where_for_groups
|
144
|
-
/WHERE.*"?reports"?.employee_id IN \(2,3\)/
|
145
|
-
end
|
146
|
-
|
147
|
-
def where_for_urgent_body
|
148
|
-
/WHERE.*body LIKE '%URGENT%'/
|
149
|
-
end
|
150
|
-
|
151
|
-
def where_for_urgent_title
|
152
|
-
/WHERE.*"?reports"?."?title"? = 'URGENT'/
|
153
|
-
end
|
154
|
-
|
155
|
-
|
156
|
-
end
|