grouped_scope 0.6.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|