active_model_serializers-cancan 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -18,6 +18,8 @@ Or install it yourself as:
18
18
 
19
19
  ## Usage
20
20
 
21
+ ### Associations
22
+
21
23
  `hasOne` and `hasMany` serializer macros now support an additional property, `authorize`. Associations with this property set to true will be authorized and filtered via CanCan. For example:
22
24
 
23
25
  ```ruby
@@ -27,11 +29,45 @@ class PostSerializer < ActiveModel::Serializer
27
29
  has_one :author, authorize: true
28
30
  has_many :comments, authorize: true
29
31
  end
30
-
31
32
  ```
32
33
 
34
+ ### Helpers
35
+
33
36
  Serializers now also have access to the same helpers as controllers, namely `current_ability`, `can?`, and `cannot?`.
34
37
 
38
+ ### Ability Serialization
39
+
40
+ Use the `abilities` helper method to add an `abilities` key to the serialized data. For example:
41
+
42
+ ```ruby
43
+ class PostSerializer < ActiveModel::Serializer
44
+ attributes :id
45
+ abilities :show, :update
46
+ end
47
+
48
+ @post.as_json # { id: 1, abilities: { show: true, update: false } }
49
+ ```
50
+
51
+ #### RESTful Alias
52
+
53
+ If `:restful` is passed as an ability it will expand to the 7 default
54
+ RESTful actions: `:index, :show, :new, :create, :edit, :update, :destroy`
55
+
56
+ #### Overriding an Ability
57
+
58
+ Abilities are checked by calling the `can_#{action}?` method. By overriding this method the result for the ability can be customized. For example:
59
+
60
+ ```ruby
61
+ class PostSerializer < ActiveModel::Serializer
62
+ attributes :id
63
+ abilities :show
64
+
65
+ def can_show?
66
+ session[:wizard_started] && can?(:show, object)
67
+ end
68
+ end
69
+ ```
70
+
35
71
  ## Contributing
36
72
 
37
73
  1. Fork it
data/Rakefile CHANGED
@@ -1 +1,7 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new('spec')
5
+
6
+ # If you want to make this the default task
7
+ task :default => :spec
@@ -16,6 +16,10 @@ Gem::Specification.new do |gem|
16
16
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
17
  gem.require_paths = ["lib"]
18
18
 
19
- gem.add_dependency "active_model_serializers", "~> 0.7.0"
20
- gem.add_dependency "cancan", "~> 1.6.9"
19
+ gem.add_dependency 'active_model_serializers'
20
+ gem.add_dependency 'cancan', '~> 1.6'
21
+
22
+ gem.add_development_dependency 'bundler', '~> 1.3'
23
+ gem.add_development_dependency 'rake'
24
+ gem.add_development_dependency 'rspec'
21
25
  end
@@ -1 +1 @@
1
- require "active_model_serializers/cancan"
1
+ require "active_model_serializers/cancan"
@@ -1,2 +1,6 @@
1
- require "active_model_serializers/cancan/version"
2
- require "active_model_serializers/cancan/associations"
1
+ require 'cancan'
2
+ require 'active_model_serializers'
3
+ require 'active_model_serializers/cancan/version'
4
+ require 'active_model_serializers/cancan/helpers'
5
+ require 'active_model_serializers/cancan/associations'
6
+ require 'active_model_serializers/cancan/abilities'
@@ -0,0 +1,46 @@
1
+ module ActiveModel
2
+ class Serializer
3
+ module CanCan
4
+ module Abilities
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ class_attribute :cancan_actions
9
+ end
10
+
11
+ module ClassMethods
12
+ def abilities(*actions)
13
+ self.cancan_actions = expand_cancan_actions(actions)
14
+ cancan_actions.each do |action|
15
+ method = "can_#{action}?".to_sym
16
+ unless method_defined?(method)
17
+ define_method method do
18
+ can? action, object
19
+ end
20
+ end
21
+ end
22
+ attributes :abilities
23
+ end
24
+
25
+ private
26
+ def expand_cancan_actions(actions)
27
+ if actions.include? :restful
28
+ actions.delete :restful
29
+ actions |= [:index, :show, :new, :create, :edit, :update, :destroy]
30
+ end
31
+ actions
32
+ end
33
+ end
34
+
35
+ def abilities
36
+ cancan_actions.inject({}) do |hash, action|
37
+ hash[action] = send("can_#{action}?")
38
+ hash
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ ActiveModel::Serializer.send :include, ActiveModel::Serializer::CanCan::Abilities
@@ -1,6 +1,3 @@
1
- require 'cancan'
2
- require 'active_model_serializers'
3
-
4
1
  module ActiveModel
5
2
  class Serializer
6
3
  module Associations #:nodoc:
@@ -10,25 +7,13 @@ module ActiveModel
10
7
  !!option(:authorize)
11
8
  end
12
9
 
13
- def current_ability
14
- Ability.new(source_serializer.options[:scope])
15
- end
16
-
17
- def can?(*args)
18
- current_ability.can? *args
19
- end
20
-
21
- def cannot?
22
- current_ability.cannot? *args
23
- end
24
-
25
10
  end
26
11
 
27
12
  class HasMany #:nodoc:
28
13
 
29
14
  def serialize_with_cancan
30
15
  return serialize_without_cancan unless authorize?
31
- associated_object.select{|o| current_ability.can?(:read, o)}.map do |item|
16
+ associated_object.select{|o| source_serializer.can?(:read, o)}.map do |item|
32
17
  find_serializable(item).serializable_hash
33
18
  end
34
19
  end
@@ -39,7 +24,7 @@ module ActiveModel
39
24
  class HasOne #:nodoc:
40
25
 
41
26
  def serialize_with_cancan
42
- return nil unless !authorize? || current_ability.can?(:read, associated_object)
27
+ return nil unless !authorize? || source_serializer.can?(:read, associated_object)
43
28
  serialize_without_cancan
44
29
  end
45
30
  alias_method_chain :serialize, :cancan
@@ -47,4 +32,4 @@ module ActiveModel
47
32
  end
48
33
  end
49
34
  end
50
- end
35
+ end
@@ -0,0 +1,21 @@
1
+ module ActiveModel
2
+ class Serializer
3
+ module CanCan
4
+ module Helpers
5
+ def current_ability
6
+ Ability.new(options[:scope])
7
+ end
8
+
9
+ def can?(*args)
10
+ current_ability.can? *args
11
+ end
12
+
13
+ def cannot?
14
+ current_ability.cannot? *args
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ ActiveModel::Serializer.send :include, ActiveModel::Serializer::CanCan::Helpers
@@ -1,7 +1,7 @@
1
1
  module ActiveModel
2
2
  module Serializers
3
3
  module Cancan
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.2"
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveModel::Serializer::CanCan::Abilities do
4
+ let(:user) { User.first }
5
+ let(:category) { Category.first }
6
+
7
+ class MockAbility
8
+ include CanCan::Ability
9
+ def initialize(user)
10
+ can :manage, Category
11
+ cannot :read, Category
12
+ end
13
+ end
14
+
15
+ describe '.abilities' do
16
+ let(:serializer) do
17
+ Class.new(ActiveModel::Serializer) do
18
+ attributes :id
19
+ abilities :restful, :foo
20
+ def current_ability
21
+ MockAbility.new(nil)
22
+ end
23
+
24
+ def can_foo?
25
+ true
26
+ end
27
+ end
28
+ end
29
+
30
+ let(:category_serializer) { serializer.new(category, scope: user) }
31
+
32
+ context 'serializable_hash' do
33
+ subject { category_serializer.serializable_hash }
34
+ its(:keys) { should eq [:id, :abilities] }
35
+ end
36
+
37
+ context 'abilities key' do
38
+ subject { category_serializer.serializable_hash[:abilities] }
39
+ its([:restful]) { should be_nil }
40
+ its([:update]) { should be_true }
41
+ its([:show]) { should be_false }
42
+ its([:foo]) { should be_true }
43
+ end
44
+ end
45
+ end
@@ -75,4 +75,4 @@ describe ActiveModel::Serializer::Associations do
75
75
 
76
76
  end
77
77
 
78
- end
78
+ end
@@ -43,4 +43,4 @@ RSpec.configure do |config|
43
43
  Project.delete_all
44
44
  Category.delete_all
45
45
  end
46
- end
46
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_model_serializers-cancan
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,24 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-20 00:00:00.000000000 Z
12
+ date: 2013-06-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: active_model_serializers
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ~>
19
+ - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: 0.7.0
21
+ version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - ~>
27
+ - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
- version: 0.7.0
29
+ version: '0'
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: cancan
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -34,7 +34,7 @@ dependencies:
34
34
  requirements:
35
35
  - - ~>
36
36
  - !ruby/object:Gem::Version
37
- version: 1.6.9
37
+ version: '1.6'
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,7 +42,55 @@ dependencies:
42
42
  requirements:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
- version: 1.6.9
45
+ version: '1.6'
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.3'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
46
94
  description:
47
95
  email:
48
96
  - ghempton@gmail.com
@@ -60,8 +108,11 @@ files:
60
108
  - init.rb
61
109
  - lib/active_model_serializers-cancan.rb
62
110
  - lib/active_model_serializers/cancan.rb
111
+ - lib/active_model_serializers/cancan/abilities.rb
63
112
  - lib/active_model_serializers/cancan/associations.rb
113
+ - lib/active_model_serializers/cancan/helpers.rb
64
114
  - lib/active_model_serializers/cancan/version.rb
115
+ - spec/active_model_serializers/cancan/abilities_spec.rb
65
116
  - spec/active_model_serializers/cancan/associations_spec.rb
66
117
  - spec/spec_helper.rb
67
118
  homepage: ''
@@ -89,6 +140,7 @@ signing_key:
89
140
  specification_version: 3
90
141
  summary: CanCan integration with Active Model Serializers
91
142
  test_files:
143
+ - spec/active_model_serializers/cancan/abilities_spec.rb
92
144
  - spec/active_model_serializers/cancan/associations_spec.rb
93
145
  - spec/spec_helper.rb
94
146
  has_rdoc: