scoped_rolify 0.0.4 → 0.0.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 02c456aa8ca494528222680ebc0024fc8069a91b
4
- data.tar.gz: afe192eba189a99fec5f5eed531bb46e137e8c21
3
+ metadata.gz: 6ccae7235a31e93ee0b08d01aa8f6e8b15289389
4
+ data.tar.gz: 2e9e9177bf449409e77178e480fc7f6a3808d222
5
5
  SHA512:
6
- metadata.gz: cfb764ac9b475af72a8361aebcf9cb1b2ea416187dc70eceec89e691763ac9324a3b5d13c398ee9b233e4569cf732327d9cbb5c97e013486931d27559fa818d5
7
- data.tar.gz: ad768d2fc9a2f853be116476ec50381225fcef6834789f0962cd8196d1a797ffb60b2d5451af7a3dbbd732fc1dc8642e03edd41f34f7c5ffa8611819a7d0bf7a
6
+ metadata.gz: ddb035951cee915f2c3dc380818885b82c1d34fab18746ae375e37a9a20bbfb1f086fd97f092df2e2696cfcd249526af0fd1d4dc1b132ef14bee05200c09888f
7
+ data.tar.gz: 158e81b64ab7521155e2a751b5028053e531b327837ee7d12b4273a92dc66647b2737c4db330a0695532e4b10a02a3e8a55c75fe450ecd4eefa5dfae2ebc9437
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.0.0-p353
1
+ ruby-2.0.0-p451
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ### VERSION 0.0.5
2
+
3
+ * bug fix
4
+
5
+ * enhancements
6
+ * add notion of root_resource
7
+
8
+ * backwards incompatible changes
9
+
10
+ * deprecations
11
+
12
+ * roadmap
13
+ * refactoring on root resource
14
+
1
15
  ### VERSION 0.0.4
2
16
 
3
17
  * bug fix
data/README.md CHANGED
@@ -61,6 +61,71 @@ You can't play with none persisted object
61
61
 
62
62
  Method ```with_any_scoped_role``` return an ```ActiveRecord::Relation``` of all users with all roles asked for one resource
63
63
 
64
+ ## Root Resource
65
+
66
+ In some case you can add right on child resource instead of parent resource, the problem is you haven't access directly to objects throught Parent resource, for exemple
67
+
68
+ You grant user on specifc Forum, user.add_role(:moderator, Forum.first) the Forum have one Category, if you want get all moderators of this Category you can't. This modification make this possible.
69
+
70
+ moderator_john = User.new
71
+ moderator_jane = User.new
72
+
73
+ geek_world = Category.new
74
+
75
+ geek_forum = Forum.new
76
+ nerd_forum = Forum.new
77
+
78
+ class Forum < ActiveRecord::Base
79
+ belongs_to :category
80
+
81
+ def root_resource
82
+ :category
83
+ end
84
+ end
85
+
86
+ class Category < ActiveRecord::Base
87
+ has_many :forums
88
+ end
89
+
90
+ geek_world.forums << geek_forum
91
+ geek_world.forums << nerd_forum
92
+
93
+ moderator_john.add_role(:moderator, nerd_forum)
94
+ moderator_jane.add_role(:moderator, geek_forum)
95
+
96
+ For grab all moderators of this Category
97
+
98
+ User.with_scoped_role :moderator, geek_world, root=true
99
+
100
+ ## Roadmap
101
+
102
+ Refactoring on root resource API
103
+
104
+ Change
105
+
106
+ User.with_scoped_role :moderator, geek_world, root=true
107
+
108
+ to
109
+
110
+ User.with_scoped_role :moderator, geek_world, scope: :forum
111
+
112
+ And change
113
+
114
+ class Forum < ActiveRecord::Base
115
+ belongs_to :category
116
+
117
+ def root_resource
118
+ :category
119
+ end
120
+ end
121
+
122
+ to
123
+
124
+ class Forum < ActiveRecord::Base
125
+ belongs_to :category
126
+ scoped_roles belongs_to: :category
127
+ end
128
+
64
129
  ## Contributing
65
130
 
66
131
  1. Fork it ( http://github.com/<my-github-username>/scoped_rolify/fork )
@@ -1,26 +1,34 @@
1
1
  module Rolify
2
2
  module Finders
3
3
 
4
- def with_scoped_role role_name, resource
4
+ def with_scoped_role role_name, resource, root_only=false
5
5
  ScopedRolify::Policy.new(self, resource).check_persisted!
6
- self.joins(:roles).where(rolify_constraints(role_name, resource))
6
+ self.joins(:roles).where(rolify_constraints(role_name, resource, root_only))
7
7
  end
8
8
 
9
- def with_any_scoped_role role_names, resource
9
+ def with_any_scoped_role role_names, resource, root_only=false
10
10
  ScopedRolify::Policy.new(self, resource).check_persisted!
11
- self.joins(:roles).where(rolify_constraints(role_names, resource))
11
+ self.joins(:roles).where(rolify_constraints(role_names, resource, root_only))
12
12
  end
13
13
 
14
- def rolify_constraints role_names, resource
14
+ def rolify_constraints role_names, resource, root_only=false
15
15
  raise 'You should give somes role' if role_names.nil? or (role_names||[]).empty?
16
+
16
17
  ScopedRolify::Policy.new(self, resource).check_persisted!
18
+
17
19
  table = Arel::Table.new(:roles)
20
+
18
21
  [].tap do |_constraints|
19
22
  Array.wrap(role_names).each do |name|
20
23
  _constraints << [].tap do |_constraint|
21
24
  _constraint << table[:name].eq(name)
22
- _constraint << table[:resource_type].eq(resource.class.name)
23
- _constraint << table[:resource_id].eq(resource.id)
25
+ if root_only
26
+ _constraint << table[:root_resource_type].eq(resource.class.name)
27
+ _constraint << table[:root_resource_id].eq(resource.id)
28
+ else
29
+ _constraint << table[:resource_type].eq(resource.class.name)
30
+ _constraint << table[:resource_id].eq(resource.id)
31
+ end
24
32
  end.reduce(:and)
25
33
  end
26
34
  end.reduce(:or)
@@ -8,7 +8,7 @@ module ScopedRolify
8
8
 
9
9
  def check_persisted!
10
10
  check!
11
- raise PersitenceError, "You should ask on persisted resource" unless self.resource.persisted?
11
+ raise PersistenceError, "You should ask on persisted resource" unless self.resource.persisted?
12
12
  end
13
13
 
14
14
  end
@@ -12,25 +12,59 @@ module Rolify
12
12
  end
13
13
 
14
14
  def has_role?(role_name, resource = nil)
15
+ root_resource = resource.respond_to?(:root_resource) ? resource.send(resource.root_resource) : nil
15
16
  if self.new_record?
16
- self.roles.detect { |r| r.name.to_s == role_name.to_s && (r.resource == resource || resource.nil?) }
17
+ self.roles.detect { |r| r.name.to_s == role_name.to_s && (r.resource == resource || resource.nil?) && (r.root_resource == root_resource || root_resource.nil?) }
17
18
  else
18
- self.class.adapter.where(self.roles, :name => role_name, :resource => resource)
19
+ self.class.adapter.where(self.roles, name: role_name, resource: resource, root_resource: root_resource)
19
20
  end.present?
20
21
  end
21
22
 
22
23
  private
23
24
 
24
25
  def add_resourced_role(role_name, resource)
26
+ root_resource = resource.respond_to?(:root_resource) ? resource.send(resource.root_resource) : nil
25
27
  if self.new_record?
26
- self.class.adapter.role_class.new(name: role_name, resource: resource).tap do |role|
28
+ role = self.class.adapter.role_class.new(name: role_name, resource: resource, root_resource: root_resource).tap do |role|
27
29
  self.roles << role
28
30
  if Rolify.dynamic_shortcuts and !self.respond_to?("is_#{role_name}?".to_sym)
29
31
  self.class.define_dynamic_method(role_name, resource)
30
32
  end
31
33
  end
32
34
  else
35
+ role = add_role_with_root(role_name, resource, root_resource)
36
+ end
37
+ add_role_to_resource(role)
38
+ load_dynamic_shortcuts(role_name, resource)
39
+ role
40
+ end
41
+
42
+ def load_dynamic_shortcuts(role_name, resource)
43
+ if Rolify.dynamic_shortcuts and !self.respond_to?("is_#{role_name}?".to_sym)
44
+ self.class.define_dynamic_method(role_name, resource)
45
+ end
46
+ end
47
+
48
+ def add_role_to_resource(role)
49
+ self.roles << role unless self.roles.include?(role)
50
+ end
51
+
52
+ def add_role_with_root(role_name, resource, root_resource)
53
+ unless root_resource
33
54
  add_role(role_name, resource)
55
+ else
56
+ conditions = {
57
+ name: role_name.to_s,
58
+ resource_type: resource.class.name,
59
+ resource_id: resource.id,
60
+ }
61
+ if root_resource
62
+ conditions.merge!({ root_resource_type: (root_resource.is_a?(Class) ? root_resource.to_s : root_resource.class.name) })
63
+ unless root_resource.is_a?(Class) # Useless for the moment (Already false)
64
+ conditions.merge!({ root_resource_id: root_resource.id })
65
+ end
66
+ end
67
+ self.class.adapter.role_class.where(conditions).first_or_create
34
68
  end
35
69
  end
36
70
 
@@ -1,3 +1,3 @@
1
1
  module ScopedRolify
2
- VERSION = '0.0.4'
2
+ VERSION = '0.0.5'
3
3
  end
@@ -1,28 +1,48 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Rolify::Finders do
4
- let(:resource) { Forum.first }
4
+ let(:resource) { Forum.where(name: 'forum 1').first }
5
5
  let(:admin) { User.where(login: 'admin').first }
6
6
 
7
7
  before { admin.add_role(:admin, resource) }
8
8
 
9
- subject { User }
10
-
11
- it { expect { subject.with_scoped_role(:admin, Forum) }.to raise_error InstanceResourceError }
12
- it { expect { subject.with_scoped_role(:admin, resource) }.to_not raise_error }
9
+ it { expect { User.with_scoped_role(:admin, Forum) }.to raise_error InstanceResourceError }
10
+ it { expect { User.with_scoped_role(:admin, resource) }.to_not raise_error }
13
11
 
14
12
  context 'regular way' do
15
- it { subject.with_scoped_role(:admin, resource).should eq([admin]) }
13
+ it { User.with_scoped_role(:admin, resource).should eq([admin]) }
16
14
  end
17
15
 
18
16
  context '#with_any_scoped_role' do
19
- let(:moderator) { subject.where(login: 'moderator').first }
17
+ let(:moderator) { User.where(login: 'moderator').first }
20
18
  before { moderator.add_role(:moderator, resource) }
21
19
  it do
22
- expect(subject.with_any_scoped_role([:admin, :moderator], resource)).to be_a(ActiveRecord::Relation)
20
+ expect(User.with_any_scoped_role([:admin, :moderator], resource)).to be_a(ActiveRecord::Relation)
23
21
  end
24
22
  it do
25
- expect(subject.with_any_scoped_role([:admin, :moderator], resource).to_a).to eq([admin, moderator])
23
+ expect(User.with_any_scoped_role([:admin, :moderator], resource).to_a).to eq([admin, moderator])
24
+ end
25
+ end
26
+
27
+ context 'with root resource' do
28
+ let(:root_resource) { Category.where(name: 'category 1').first }
29
+ let(:another_resource) { Forum.where(name: 'forum 2').first }
30
+ let(:super_admin) { User.where(login: 'super admin').first }
31
+ let(:moderator) { User.where(login: 'moderator').first }
32
+
33
+ before do
34
+ root_resource.forums << resource
35
+ root_resource.forums << another_resource
36
+ end
37
+
38
+ context 'add role to user' do
39
+ before do
40
+ super_admin.add_scope_role(:super_admin, resource)
41
+ moderator.add_scope_role(:super_admin, another_resource)
42
+ end
43
+
44
+ it('should retreive super_admin') { expect(User.with_scoped_role(:super_admin, resource).to_a).to eq([super_admin]) }
45
+ it('should retreive all user for Category') { expect(User.with_scoped_role(:super_admin, root_resource, true).to_a).to eq([super_admin, moderator]) }
26
46
  end
27
47
  end
28
48
  end
@@ -17,6 +17,7 @@ describe Rolify::Role do
17
17
 
18
18
  it { expect { subject.add_scope_role(:admin, resource) }.to_not raise_error }
19
19
  it { should have_role :admin, resource }
20
+ it { expect(User.with_scoped_role(:admin, resource).to_a).to eq([user]) }
20
21
  end
21
22
 
22
23
  context 'new record way' do
@@ -33,5 +34,38 @@ describe Rolify::Role do
33
34
  end
34
35
  end
35
36
 
36
- end
37
+ context 'with root resource' do
38
+ context 'persisted way' do
39
+ let(:root_resource) { Category.first }
37
40
 
41
+ before { root_resource.forums << resource }
42
+
43
+ context 'add role to user' do
44
+ before { subject.add_scope_role(:admin, resource) }
45
+ it('should retreive user') do
46
+ expect(
47
+ User.joins(:roles).where(
48
+ Role.where(name: :admin, resource_type: 'Forum', resource_id: resource.id,
49
+ root_resource_type: 'Category', root_resource_id: root_resource.id).arel.constraints.first
50
+ ).to_a
51
+ ).to eq([subject])
52
+ end
53
+ end
54
+ end
55
+
56
+ context 'unpersisted way' do
57
+ let(:root_resource) { Category.new(name: 'UnCategoized') }
58
+ let(:resource) { Forum.new(name: 'forum 42') }
59
+ let(:user) { User.new(login: 'John Doe') }
60
+
61
+ before { root_resource.forums << resource }
62
+
63
+ it { expect(root_resource.forums).to eq([resource]) }
64
+
65
+ context 'add role to user' do
66
+ before { user.add_scope_role(:admin, resource) }
67
+ it { should have_role :admin, resource }
68
+ end
69
+ end
70
+ end
71
+ end
data/spec/spec_helper.rb CHANGED
@@ -10,9 +10,14 @@ Coveralls.wear!
10
10
  ENV['ADAPTER'] ||= 'active_record'
11
11
 
12
12
  load File.dirname(__FILE__) + "/support/adapters/#{ENV['ADAPTER']}.rb"
13
- load File.dirname(__FILE__) + '/support/data.rb'
14
13
 
15
- RSpec.configure do |c|
16
- c.run_all_when_everything_filtered = true
14
+ RSpec.configure do |config|
15
+ config.filter_run focused: true
16
+ config.run_all_when_everything_filtered = true
17
+
18
+ config.before(:each) do
19
+ [ User, Role, Forum, Category].each &:destroy_all
20
+ load File.dirname(__FILE__) + '/support/data.rb'
21
+ end
17
22
  end
18
23
 
@@ -13,11 +13,20 @@ end
13
13
  class Role < ActiveRecord::Base
14
14
  has_and_belongs_to_many :users, join_table: :users_roles
15
15
  belongs_to :resource, polymorphic: true
16
+ belongs_to :root_resource, polymorphic: true
16
17
 
17
18
  extend Rolify::Adapter::Scopes
18
19
  end
19
20
 
20
- # Resources classes
21
21
  class Forum < ActiveRecord::Base
22
- #resourcify done during specs setup to be able to use custom user classes
22
+ belongs_to :category
23
+
24
+ def root_resource
25
+ :category
26
+ end
27
+ end
28
+
29
+ # Resources classes
30
+ class Category < ActiveRecord::Base
31
+ has_many :forums
23
32
  end
data/spec/support/data.rb CHANGED
@@ -1,10 +1,6 @@
1
- # Users
2
- User.destroy_all
3
1
  User.create login: 'admin'
2
+ User.create login: 'super admin'
4
3
  User.create login: 'moderator'
5
-
6
- # Roles
7
- Role.destroy_all
8
-
9
- # Resources
10
4
  Forum.create name: 'forum 1'
5
+ Forum.create name: 'forum 2'
6
+ Category.create name: 'category 1'
@@ -8,6 +8,7 @@ ActiveRecord::Schema.define do
8
8
  create_table(:roles) do |t|
9
9
  t.string :name
10
10
  t.references :resource, polymorphic: true
11
+ t.references :root_resource, polymorphic: true
11
12
  t.timestamps
12
13
  end
13
14
 
@@ -18,6 +19,10 @@ ActiveRecord::Schema.define do
18
19
 
19
20
  create_table(:forums) do |t|
20
21
  t.string :name
22
+ t.integer :category_id
21
23
  end
22
24
 
25
+ create_table(:categories) do |t|
26
+ t.string :name
27
+ end
23
28
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scoped_rolify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel AZEMAR
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-11 00:00:00.000000000 Z
11
+ date: 2014-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rolify
@@ -133,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
133
  version: '0'
134
134
  requirements: []
135
135
  rubyforge_project:
136
- rubygems_version: 2.0.14
136
+ rubygems_version: 2.2.2
137
137
  signing_key:
138
138
  specification_version: 4
139
139
  summary: This is a monkey patch of rolify