required_scopes 1.0.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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +29 -0
- data/Gemfile +17 -0
- data/LICENSE.txt +22 -0
- data/README.md +277 -0
- data/Rakefile +6 -0
- data/lib/required_scopes.rb +17 -0
- data/lib/required_scopes/active_record/base.rb +235 -0
- data/lib/required_scopes/active_record/relation.rb +121 -0
- data/lib/required_scopes/active_record/version_compatibility.rb +157 -0
- data/lib/required_scopes/errors.rb +48 -0
- data/lib/required_scopes/version.rb +3 -0
- data/required_scopes.gemspec +56 -0
- data/spec/required_scopes/helpers/database_helper.rb +174 -0
- data/spec/required_scopes/helpers/system_helpers.rb +98 -0
- data/spec/required_scopes/system/associations_system_spec.rb +150 -0
- data/spec/required_scopes/system/base_scope_system_spec.rb +71 -0
- data/spec/required_scopes/system/basic_system_spec.rb +121 -0
- data/spec/required_scopes/system/inheritance_system_spec.rb +67 -0
- data/spec/required_scopes/system/methods_system_spec.rb +312 -0
- data/spec/required_scopes/system/static_scopes_system_spec.rb +31 -0
- metadata +141 -0
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'active_record/migration'
|
3
|
+
|
4
|
+
module RequiredScopes
|
5
|
+
module Helpers
|
6
|
+
module SystemHelpers
|
7
|
+
def migrate(&block)
|
8
|
+
migration_class = Class.new(::ActiveRecord::Migration)
|
9
|
+
metaclass = migration_class.class_eval { class << self; self; end }
|
10
|
+
metaclass.instance_eval { define_method(:up, &block) }
|
11
|
+
|
12
|
+
::ActiveRecord::Migration.suppress_messages do
|
13
|
+
migration_class.migrate(:up)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def define_model_class(name, table_name, &block)
|
18
|
+
model_class = Class.new(::ActiveRecord::Base)
|
19
|
+
::Object.send(:remove_const, name) if ::Object.const_defined?(name)
|
20
|
+
::Object.const_set(name, model_class)
|
21
|
+
model_class.table_name = table_name
|
22
|
+
model_class.class_eval(&block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_standard_system_spec_tables!
|
26
|
+
migrate do
|
27
|
+
drop_table :rec_spec_users rescue nil
|
28
|
+
create_table :rec_spec_users do |t|
|
29
|
+
t.string :name, :null => false
|
30
|
+
t.string :favorite_color
|
31
|
+
t.string :favorite_taste
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def define_color_and_taste_scopes!
|
37
|
+
::User.class_eval do
|
38
|
+
must_scope_by :color, :taste
|
39
|
+
|
40
|
+
scope :red, lambda { where(:favorite_color => 'red') }, :satisfies => :color
|
41
|
+
scope :green, lambda { where(:favorite_color => 'green') }, :satisfies => :color
|
42
|
+
|
43
|
+
scope :salty, lambda { where(:favorite_taste => 'salty') }, :satisfies => :taste
|
44
|
+
scope :sweet, lambda { where(:favorite_taste => 'sweet') }, :satisfies => :taste
|
45
|
+
|
46
|
+
scope :red_and_salty, lambda { where(:favorite_color => 'red', :favorite_taste => 'salty') }, :satisfies => [ :color, :taste ]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def should_raise_missing_scopes(triggering_method, required, satisfied, options = { })
|
51
|
+
e = result = nil
|
52
|
+
|
53
|
+
begin
|
54
|
+
result = yield
|
55
|
+
rescue RequiredScopes::Errors::RequiredScopeCategoriesNotSatisfiedError => rscnse
|
56
|
+
e = rscnse
|
57
|
+
end
|
58
|
+
|
59
|
+
raise "Expected a scopes-not-satisfied error, but got none" unless e
|
60
|
+
|
61
|
+
expected_model_class = options[:model_class] || ::User
|
62
|
+
|
63
|
+
e.class.should == RequiredScopes::Errors::RequiredScopeCategoriesNotSatisfiedError
|
64
|
+
e.model_class.should == expected_model_class
|
65
|
+
e.current_relation.should be
|
66
|
+
e.current_relation.kind_of?(::ActiveRecord::Relation).should be
|
67
|
+
e.triggering_method.should == triggering_method
|
68
|
+
e.required_categories.sort_by(&:to_s).should == required.sort_by(&:to_s)
|
69
|
+
e.satisfied_categories.sort_by(&:to_s).should == satisfied.sort_by(&:to_s)
|
70
|
+
|
71
|
+
expected_missing_categories = required - satisfied
|
72
|
+
e.missing_categories.sort_by(&:to_s).should == expected_missing_categories.sort_by(&:to_s)
|
73
|
+
|
74
|
+
e.message.should match(/#{expected_model_class.name}/)
|
75
|
+
e.message.should match(/#{expected_missing_categories.sort_by(&:to_s).join(", ")}/)
|
76
|
+
end
|
77
|
+
|
78
|
+
def create_standard_system_spec_models!
|
79
|
+
define_model_class(:User, 'rec_spec_users') { }
|
80
|
+
end
|
81
|
+
|
82
|
+
def create_standard_system_spec_instances!
|
83
|
+
@red_salty = ::User.create!(:name => 'red-salty', :favorite_color => 'red', :favorite_taste => 'salty')
|
84
|
+
@green_salty = ::User.create!(:name => 'green-salty', :favorite_color => 'green', :favorite_taste => 'salty')
|
85
|
+
@blue_salty = ::User.create!(:name => 'blue-salty', :favorite_color => 'blue', :favorite_taste => 'salty')
|
86
|
+
@red_sweet = ::User.create!(:name => 'red-sweet', :favorite_color => 'red', :favorite_taste => 'sweet')
|
87
|
+
@green_sweet = ::User.create!(:name => 'green-sweet', :favorite_color => 'green', :favorite_taste => 'sweet')
|
88
|
+
@blue_sweet = ::User.create!(:name => 'blue-sweet', :favorite_color => 'blue', :favorite_taste => 'sweet')
|
89
|
+
end
|
90
|
+
|
91
|
+
def drop_standard_system_spec_tables!
|
92
|
+
migrate do
|
93
|
+
drop_table :rec_spec_users rescue nil
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'required_scopes'
|
2
|
+
require 'required_scopes/helpers/database_helper'
|
3
|
+
require 'required_scopes/helpers/system_helpers'
|
4
|
+
|
5
|
+
describe "RequiredScopes and associations" do
|
6
|
+
include RequiredScopes::Helpers::SystemHelpers
|
7
|
+
|
8
|
+
before :each do
|
9
|
+
@dh = RequiredScopes::Helpers::DatabaseHelper.new
|
10
|
+
@dh.setup_activerecord!
|
11
|
+
|
12
|
+
migrate do
|
13
|
+
drop_table :rec_spec_groups rescue nil
|
14
|
+
create_table :rec_spec_groups do |t|
|
15
|
+
t.string :name, :null => false
|
16
|
+
end
|
17
|
+
|
18
|
+
drop_table :rec_spec_users rescue nil
|
19
|
+
create_table :rec_spec_users do |t|
|
20
|
+
t.string :name, :null => false
|
21
|
+
t.integer :group_id
|
22
|
+
t.string :favorite_color
|
23
|
+
end
|
24
|
+
|
25
|
+
drop_table :rec_spec_user_preferences rescue nil
|
26
|
+
create_table :rec_spec_user_preferences do |t|
|
27
|
+
t.integer :user_id
|
28
|
+
t.string :preference
|
29
|
+
end
|
30
|
+
|
31
|
+
drop_table :rec_spec_categories rescue nil
|
32
|
+
create_table :rec_spec_categories do |t|
|
33
|
+
t.string :name
|
34
|
+
end
|
35
|
+
|
36
|
+
drop_table :rec_spec_categories_users rescue nil
|
37
|
+
create_table :rec_spec_categories_users, :id => false do |t|
|
38
|
+
t.integer :user_id
|
39
|
+
t.integer :category_id
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
define_model_class(:User, :rec_spec_users) do
|
44
|
+
must_scope_by :color
|
45
|
+
belongs_to :group
|
46
|
+
has_one :user_preference
|
47
|
+
has_and_belongs_to_many :categories, :join_table => :rec_spec_categories_users
|
48
|
+
|
49
|
+
scope :red, lambda { where(:favorite_color => :red) }, :satisfies => :color
|
50
|
+
end
|
51
|
+
|
52
|
+
define_model_class(:Group, :rec_spec_groups) do
|
53
|
+
has_many :users
|
54
|
+
end
|
55
|
+
|
56
|
+
define_model_class(:UserPreference, :rec_spec_user_preferences) do
|
57
|
+
belongs_to :user
|
58
|
+
|
59
|
+
must_scope_by :prefcolor
|
60
|
+
end
|
61
|
+
|
62
|
+
define_model_class(:Category, :rec_spec_categories) do
|
63
|
+
has_and_belongs_to_many :users, :join_table => :rec_spec_categories_users
|
64
|
+
|
65
|
+
must_scope_by :catcolor
|
66
|
+
end
|
67
|
+
|
68
|
+
@group1 = ::Group.create!(:name => 'Group 1')
|
69
|
+
@user1 = ::User.create!(:name => 'g1u1', :favorite_color => 'red', :group => @group1)
|
70
|
+
@user2 = ::User.create!(:name => 'g1u2', :favorite_color => 'green', :group => @group1)
|
71
|
+
|
72
|
+
@user1pref = ::UserPreference.create!(:user => @user1, :preference => 'u1p')
|
73
|
+
@user2pref = ::UserPreference.create!(:user => @user2, :preference => 'u2p')
|
74
|
+
|
75
|
+
@cat1 = ::Category.create!(:name => 'c1')
|
76
|
+
@cat2 = ::Category.create!(:name => 'c2')
|
77
|
+
|
78
|
+
@cat1.users << @user1
|
79
|
+
@cat1.users << @user2
|
80
|
+
@cat1.save!
|
81
|
+
|
82
|
+
@cat2.users << @user1
|
83
|
+
@cat2.users << @user2
|
84
|
+
@cat2.save!
|
85
|
+
end
|
86
|
+
|
87
|
+
after :each do
|
88
|
+
migrate do
|
89
|
+
drop_table :rec_spec_groups rescue nil
|
90
|
+
drop_table :rec_spec_users rescue nil
|
91
|
+
drop_table :rec_spec_user_preferences rescue nil
|
92
|
+
drop_table :rec_spec_categories rescue nil
|
93
|
+
drop_table :rec_spec_categories_users rescue nil
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should require a scope when accessed directly" do
|
98
|
+
lambda { ::User.where(:group_id => @group1.id).to_a }.should raise_error(RequiredScopes::Errors::RequiredScopeCategoriesNotSatisfiedError)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should not require a scope when accessed via an association" do
|
102
|
+
@group1.users.map(&:id).sort.should == [ @user1, @user2 ].map(&:id).sort
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should not require a scope when accessed via an association, with eager loading" do
|
106
|
+
Group.includes(:users).find(@group1.id).users.map(&:id).sort.should == [ @user1, @user2 ].map(&:id).sort
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should not require a scope when accessed via #joins" do
|
110
|
+
Group.joins(:users).find(@group1.id).users.map(&:id).sort.should == [ @user1, @user2 ].map(&:id).sort
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should not require a scope when accessed via #eager_load" do
|
114
|
+
Group.eager_load(:users).find(@group1.id).users.map(&:id).sort.should == [ @user1, @user2 ].map(&:id).sort
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should not require a scope when accessed via #preload" do
|
118
|
+
Group.preload(:users).find(@group1.id).users.map(&:id).sort.should == [ @user1, @user2 ].map(&:id).sort
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should not require a scope when accessed via #references" do
|
122
|
+
if ::RequiredScopes::ActiveRecord::VersionCompatibility.supports_references_method?
|
123
|
+
Group.references(:users).find(@group1.id).users.map(&:id).sort.should == [ @user1, @user2 ].map(&:id).sort
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should not require a scope when accessed via has_one" do
|
128
|
+
@user1.user_preference.should == @user1pref
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should not require a scope when accessed via has_one, with eager loading" do
|
132
|
+
User.includes(:user_preference).red.find(@user1.id).id.should == @user1pref.id
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should not require a scope when accessed via belongs_to" do
|
136
|
+
@user1pref.user.should == @user1
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should not require a scope when accessed via has_one, with eager loading" do
|
140
|
+
UserPreference.includes(:user).all_scope_categories_satisfied.find(@user1pref.id).id.should == @user1.id
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should not require a scope when accessed via has_and_belongs_to_many" do
|
144
|
+
@user1.categories.map(&:id).sort.should == [ @cat1, @cat2 ].map(&:id).sort
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should not require a scope when accessed via has_and_belongs_to_many, with eager loading" do
|
148
|
+
::User.includes(:categories).all_scope_categories_satisfied.find(@user1).categories.map(&:id).should == [ @cat1, @cat2 ].map(&:id).sort
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'required_scopes'
|
2
|
+
require 'required_scopes/helpers/database_helper'
|
3
|
+
require 'required_scopes/helpers/system_helpers'
|
4
|
+
|
5
|
+
describe "RequiredScopes base scope operations" do
|
6
|
+
include RequiredScopes::Helpers::SystemHelpers
|
7
|
+
|
8
|
+
before :each do
|
9
|
+
@dh = RequiredScopes::Helpers::DatabaseHelper.new
|
10
|
+
@dh.setup_activerecord!
|
11
|
+
|
12
|
+
create_standard_system_spec_tables!
|
13
|
+
create_standard_system_spec_models!
|
14
|
+
create_standard_system_spec_instances!
|
15
|
+
|
16
|
+
::User.class_eval do
|
17
|
+
base_scope_required!
|
18
|
+
|
19
|
+
base_scope :red, lambda { where(:favorite_color => 'red') }
|
20
|
+
base_scope :green, lambda { where(:favorite_color => 'green') }
|
21
|
+
|
22
|
+
scope :salty, lambda { where(:favorite_taste => 'salty') }
|
23
|
+
|
24
|
+
class << self
|
25
|
+
def blue
|
26
|
+
base_scope_satisfied.where(:favorite_color => 'blue')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
after :each do
|
33
|
+
drop_standard_system_spec_tables!
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should require the base scope" do
|
37
|
+
e = nil
|
38
|
+
|
39
|
+
begin
|
40
|
+
::User.all.to_a
|
41
|
+
rescue RequiredScopes::Errors::BaseScopeNotSatisfiedError => bsnse
|
42
|
+
e = bsnse
|
43
|
+
end
|
44
|
+
|
45
|
+
e.should be
|
46
|
+
e.class.should == RequiredScopes::Errors::BaseScopeNotSatisfiedError
|
47
|
+
e.model_class.should == ::User
|
48
|
+
|
49
|
+
e.current_relation.should be
|
50
|
+
e.current_relation.kind_of?(::ActiveRecord::Relation).should be
|
51
|
+
e.triggering_method.should == :exec_queries
|
52
|
+
|
53
|
+
e.required_categories.should == [ :base ]
|
54
|
+
e.satisfied_categories.should == [ ]
|
55
|
+
e.missing_categories.should == [ :base ]
|
56
|
+
|
57
|
+
e.message.should match(/base scope/i)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should work if a base scope is used" do
|
61
|
+
::User.red.to_a
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should work if a class method satisfying the base scope is used" do
|
65
|
+
::User.blue.to_a
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should work if you manually tell it that the base scope is satisfied" do
|
69
|
+
::User.base_scope_satisfied.to_a
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'required_scopes'
|
2
|
+
require 'required_scopes/helpers/database_helper'
|
3
|
+
require 'required_scopes/helpers/system_helpers'
|
4
|
+
|
5
|
+
describe "RequiredScopes basic operations" do
|
6
|
+
include RequiredScopes::Helpers::SystemHelpers
|
7
|
+
|
8
|
+
before :each do
|
9
|
+
@dh = RequiredScopes::Helpers::DatabaseHelper.new
|
10
|
+
@dh.setup_activerecord!
|
11
|
+
|
12
|
+
create_standard_system_spec_tables!
|
13
|
+
create_standard_system_spec_models!
|
14
|
+
create_standard_system_spec_instances!
|
15
|
+
|
16
|
+
define_color_and_taste_scopes!
|
17
|
+
end
|
18
|
+
|
19
|
+
after :each do
|
20
|
+
drop_standard_system_spec_tables!
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "queries" do
|
24
|
+
it "should raise if no categories are applied" do
|
25
|
+
should_raise_missing_scopes(:exec_queries, [ :color, :taste ], [ ]) { ::User.all.to_a }
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should raise if only one category is applied" do
|
29
|
+
should_raise_missing_scopes(:exec_queries, [ :color, :taste ], [ :color ]) { ::User.red.to_a }
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should not raise if both categories are individually applied" do
|
33
|
+
::User.red.salty.to_a.should == [ @red_salty ]
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should not raise if both categories are satisfied by a single scope" do
|
37
|
+
::User.red_and_salty.to_a.should == [ @red_salty ]
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should allow further qualifying the scopes, and in the middle" do
|
41
|
+
::User.where("name LIKE 'red%'").red.where("name LIKE '%salty'").salty.where("name LIKE '%d-s%'").to_a.should == [ @red_salty ]
|
42
|
+
::User.where("name LIKE 'green%'").red.salty.to_a.should == [ ]
|
43
|
+
::User.red.where("name LIKE '%sweet'").salty.to_a.should == [ ]
|
44
|
+
::User.red.salty.where("name LIKE '%sweet'").to_a.should == [ ]
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should automatically have a scope that includes all of each category" do
|
48
|
+
::User.red.ignoring_taste.to_a.sort.should == [ @red_salty, @red_sweet ].sort
|
49
|
+
::User.ignoring_color.sweet.to_a.sort.should == [ @red_sweet, @green_sweet, @blue_sweet ].sort
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should still require scopes even if #unscoped is used" do
|
53
|
+
should_raise_missing_scopes(:exec_queries, [ :color, :taste ], [ ]) { ::User.unscoped.to_a }
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should still require scopes even if #unscoped is used in a block form" do
|
57
|
+
should_raise_missing_scopes(:exec_queries, [ :color, :taste ], [ ]) { ::User.unscoped { ::User.all.to_a } }
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should allow manually saying that categories are satisfied" do
|
61
|
+
::User.red.scope_category_satisfied(:taste).to_a.sort.should == [ @red_salty, @red_sweet ].to_a
|
62
|
+
::User.scope_category_satisfied(:color).sweet.to_a.sort.should == [ @red_sweet, @green_sweet, @blue_sweet ].to_a
|
63
|
+
::User.scope_categories_satisfied(:color, :taste).to_a.sort.should ==
|
64
|
+
[ @red_sweet, @green_sweet, @blue_sweet, @red_salty, @green_salty, @blue_salty ].to_a.sort
|
65
|
+
::User.scope_categories_satisfied(:color, :taste).sweet.to_a.sort.should ==
|
66
|
+
[ @red_sweet, @green_sweet, @blue_sweet ].to_a.sort
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should allow manually saying that categories are satisfied, in a block" do
|
70
|
+
ran_block = false
|
71
|
+
::User.scope_category_satisfied(:taste) do
|
72
|
+
::User.red.to_a.sort.should == [ @red_salty, @red_sweet].to_a
|
73
|
+
ran_block = true
|
74
|
+
end
|
75
|
+
ran_block.should be
|
76
|
+
|
77
|
+
ran_block = false
|
78
|
+
::User.scope_category_satisfied(:taste) do
|
79
|
+
should_raise_missing_scopes(:exec_queries, [ :color, :taste ], [ :taste ]) { ::User.all.to_a }
|
80
|
+
ran_block = true
|
81
|
+
end
|
82
|
+
ran_block.should be
|
83
|
+
|
84
|
+
ran_block = false
|
85
|
+
::User.scope_category_satisfied(:taste) do
|
86
|
+
::User.red.to_a.sort.should == [ @red_salty, @red_sweet ].sort
|
87
|
+
ran_block = true
|
88
|
+
end
|
89
|
+
ran_block.should be
|
90
|
+
|
91
|
+
ran_block = false
|
92
|
+
::User.all_scope_categories_satisfied do
|
93
|
+
::User.all.to_a.sort.should == [ @red_salty, @red_sweet, @green_salty, @green_sweet, @blue_salty, @blue_sweet ].sort
|
94
|
+
ran_block = true
|
95
|
+
end
|
96
|
+
ran_block.should be
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should allow saying that categories are satisfied in a class method, in any position" do
|
100
|
+
::User.class_eval do
|
101
|
+
class << self
|
102
|
+
def red_and_green
|
103
|
+
scope_category_satisfied(:color).where(:favorite_color => %w{red green})
|
104
|
+
end
|
105
|
+
|
106
|
+
def green_and_blue
|
107
|
+
where(:favorite_color => %w{green blue}).scope_category_satisfied(:color)
|
108
|
+
end
|
109
|
+
|
110
|
+
def red_and_blue
|
111
|
+
where(:favorite_color => %w{red blue}).scope_category_satisfied(:color).where(:favorite_taste => %w{salty sweet})
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
::User.red_and_green.salty.to_a.sort.should == [ @red_salty, @green_salty ].sort
|
117
|
+
::User.green_and_blue.salty.to_a.sort.should == [ @green_salty, @blue_salty ].sort
|
118
|
+
::User.red_and_blue.salty.to_a.sort.should == [ @red_salty, @blue_salty ].sort
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'required_scopes'
|
2
|
+
require 'required_scopes/helpers/database_helper'
|
3
|
+
require 'required_scopes/helpers/system_helpers'
|
4
|
+
|
5
|
+
describe "RequiredScopes and inheritance" do
|
6
|
+
include RequiredScopes::Helpers::SystemHelpers
|
7
|
+
|
8
|
+
before :each do
|
9
|
+
@dh = RequiredScopes::Helpers::DatabaseHelper.new
|
10
|
+
@dh.setup_activerecord!
|
11
|
+
|
12
|
+
create_standard_system_spec_tables!
|
13
|
+
create_standard_system_spec_models!
|
14
|
+
create_standard_system_spec_instances!
|
15
|
+
end
|
16
|
+
|
17
|
+
after :each do
|
18
|
+
drop_standard_system_spec_tables!
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should combine multiple #must_scope_by declarations" do
|
22
|
+
::User.class_eval do
|
23
|
+
must_scope_by :color
|
24
|
+
must_scope_by :taste
|
25
|
+
|
26
|
+
scope :red, lambda { where(:favorite_color => 'red') }, :satisfies => :color
|
27
|
+
scope :salty, lambda { where(:favorite_taste => 'salty') }, :satisfies => :taste
|
28
|
+
end
|
29
|
+
|
30
|
+
should_raise_missing_scopes(:exec_queries, [ :color, :taste ], [ :taste ]) { ::User.salty.to_a }
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should inherit #must_scope_by in child classes" do
|
34
|
+
::User.class_eval do
|
35
|
+
must_scope_by :color
|
36
|
+
scope :red, lambda { where(:favorite_color => 'red') }, :satisfies => :color
|
37
|
+
end
|
38
|
+
|
39
|
+
class ::UserSub1 < ::User
|
40
|
+
self.table_name = ::User.table_name
|
41
|
+
|
42
|
+
must_scope_by :taste
|
43
|
+
scope :salty, lambda { where(:favorite_taste => 'salty') }, :satisfies => :taste
|
44
|
+
end
|
45
|
+
|
46
|
+
should_raise_missing_scopes(:exec_queries, [ :color, :taste ], [ :taste ], :model_class => ::UserSub1) { ::UserSub1.salty.to_a }
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should allow ignoring a required scope in a subclass" do
|
50
|
+
::User.class_eval do
|
51
|
+
must_scope_by :color
|
52
|
+
scope :red, lambda { where(:favorite_color => 'red') }, :satisfies => :color
|
53
|
+
end
|
54
|
+
|
55
|
+
class ::UserSub2 < ::User
|
56
|
+
self.table_name = ::User.table_name
|
57
|
+
|
58
|
+
must_scope_by :taste
|
59
|
+
scope :salty, lambda { where(:favorite_taste => 'salty') }, :satisfies => :taste
|
60
|
+
|
61
|
+
ignore_parent_scope_requirement :color
|
62
|
+
end
|
63
|
+
|
64
|
+
::UserSub2.salty.to_a.should be
|
65
|
+
should_raise_missing_scopes(:exec_queries, [ :taste ], [ ], :model_class => ::UserSub2) { ::UserSub2.all.to_a }
|
66
|
+
end
|
67
|
+
end
|