super_resources 1.0.0.rc1 → 1.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -15,6 +15,7 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ .DS_Store
18
19
 
19
20
  spec/dummy/log/*.log
20
21
  spec/dummy/db/*.sqlite3
data/README.md CHANGED
@@ -126,13 +126,12 @@ SuperResources derives the class of the target resource from the controller name
126
126
 
127
127
  Yes, you can adapt these to suit your needs.
128
128
 
129
- Both `resource` and `collection` accept a block, which SuperResources uses to stitch into its internal implementation, so tht any subsequent calls to these helpers uses your implementation.
130
- The block for `resource` shall answer a single instance of the resource class and the block for `collection` shall answer an array of instances of the resource class.
129
+ The `resource` and `collection` methods are used internally by the default RESTful actions provided by SuperResources, and can have their implementations customised easily. The return values of these methods are memoized for various reasons, for this you should make use of the `memoize_resource` and `memoize_collection` methods respectivley. Both methods take a block that is only executed as necessary.
131
130
 
132
131
  For example, if you wanted 'TeamsController#collection' to return only those teams that the current user has joined, you would write an implementation of `collection` that calls its super, passing a block the evalautes to the right collection:
133
132
 
134
133
  def collection
135
- super { resource_class.joined_by(current_user) }
134
+ memoize_collection { resource_class.joined_by(current_user) }
136
135
  end
137
136
 
138
137
  If that looks strange, bear in mind it's been designed so that you don't need to know how SuperResources internally uses your preferred implementation.
@@ -156,20 +155,10 @@ While SuperResource uses the `find` method as the default, you can choose anothe
156
155
 
157
156
  ### Builder Method
158
157
 
159
- SuperResources extracts the construction of a new resource into the `build_resource` method. If you need to create a new resource, say in a special action, use 'build_resource' so that SuperResource can also keep track of it (for example, make sure that `resource' answers the built object).
160
-
161
- If you need to do specialized work for the build, pass the a block to `build_resource` that evaluates to an object with the state you need. For example:
162
-
163
- build_resource do
164
- resource_class.new do |p|
165
- # initialize the state here
166
- end
167
- end
168
-
169
- More commonly, you would redefine the whole method so that it always behaves the same way for its enclosing controller:
158
+ SuperResources extracts the construction of a new resource into the `build_resource` method. If you need to do specialized work for the build, override the `build_resource` method and be sure to memoize your result:
170
159
 
171
160
  def build_resource
172
- super do
161
+ memoize_resource do
173
162
  resource_class.new do |p|
174
163
  # initialize the state here
175
164
  end
@@ -200,9 +189,9 @@ Just do it. Declare them in your controller and match them in routes. All the Su
200
189
 
201
190
  ## Acknowledgments
202
191
 
203
- SuperResources would never have happened without InheritedResources [https://github.com/josevalim/inherited_resources] existing first.
192
+ SuperResources would never have happened without [InheritedResources](https://github.com/josevalim/inherited_resources) existing first.
204
193
  We preferred the idea of abstracting and extracting RESTful actions out of all our controllers and we're not so keen on scaffolds generating
205
- un-DRY code. We used InheritedResources in a production deployed application [meetlinkshare.com], gained some experience and decided we wanted an even DRYer tool.
194
+ un-DRY code. We used InheritedResources in a production deployed application [MeetLinkShare](http://www.meetlinkshare.com), gained some experience and decided we wanted an even DRYer tool.
206
195
 
207
196
  The basic mechanics of SuperResources was hacked out during Rails Camp 12 in Tasmania, Australia and was subsequently applied to MeetLinkShare.
208
197
 
@@ -0,0 +1,13 @@
1
+ require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator'
2
+
3
+ module Rails
4
+ module Generators
5
+ class SuperControllerGenerator < Rails::Generators::ScaffoldControllerGenerator
6
+ def self.source_root
7
+ @source_root ||= File.expand_path('../templates', __FILE__)
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+
@@ -0,0 +1,9 @@
1
+ <% if namespaced? -%>
2
+ require_dependency "<%= namespaced_file_path %>/application_controller"
3
+
4
+ <% end -%>
5
+ <% module_namespacing do -%>
6
+ class <%= controller_class_name %>Controller < ApplicationController
7
+ include SuperResources::Controller
8
+ end
9
+ <% end -%>
@@ -1,7 +1,9 @@
1
1
  module SuperResources
2
2
  module Nesting
3
3
  extend ActiveSupport::Concern
4
+
4
5
  include Resources
6
+ include Routing
5
7
 
6
8
  included do
7
9
  helper_method :association_chain, :with_chain, :method_missing, :respond_to?
@@ -24,28 +26,16 @@ module SuperResources
24
26
  end
25
27
  end
26
28
 
27
- def collection(&block)
28
- if block_given?
29
- @collection = yield
30
- else
31
- @collection ||= end_of_association_chain
32
- end
29
+ def collection
30
+ memoize_collection { end_of_association_chain }
33
31
  end
34
32
 
35
- def resource(&block)
36
- if block_given?
37
- @resource = yield
38
- else
39
- @resource ||= end_of_association_chain.send(finder_method, params[:id])
40
- end
33
+ def resource
34
+ memoize_resource { end_of_association_chain.send(finder_method, params[:id]) }
41
35
  end
42
36
 
43
- def build_resource(&block)
44
- if block_given?
45
- @resource = yield
46
- else
47
- @resource ||= end_of_association_chain.build(resource_params)
48
- end
37
+ def build_resource(params={})
38
+ memoize_resource { end_of_association_chain.build(params) }
49
39
  end
50
40
 
51
41
  def nested?
@@ -82,29 +72,10 @@ module SuperResources
82
72
  route.parts \
83
73
  .select { |p| p.to_s =~ %r(_id$) } \
84
74
  .map { |p| p.to_s.gsub(/_id$/, '').to_sym }
85
- @symbols_for_association_chain
86
75
  end
87
76
 
88
77
  def with_chain(object)
89
78
  association_chain + [ object ]
90
79
  end
91
-
92
- def route
93
- @route ||= begin
94
- routes.formatter.send(:match_route, nil, path_parameters) do |route|
95
- # TODO: don't assume the first route is good, validate!
96
- # TODO: don't use break
97
- break route
98
- end
99
- end
100
- end
101
-
102
- def routes
103
- request.env['action_dispatch.routes']
104
- end
105
-
106
- def path_parameters
107
- request.env['action_dispatch.request.path_parameters'].symbolize_keys
108
- end
109
80
  end
110
81
  end
@@ -0,0 +1,9 @@
1
+ module SuperResources
2
+ class Railtie < Rails::Railtie
3
+ if config.respond_to?(:app_generators)
4
+ config.app_generators.scaffold_controller = :super_controller
5
+ else
6
+ config.generators.scaffold_controller = :super_controller
7
+ end
8
+ end
9
+ end
@@ -3,7 +3,7 @@ module SuperResources
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
- helper_method :collection, :collection=, :resource, :resource=, :resource_class, :parent, :nested?
6
+ helper_method :collection, :resource, :resource_class, :parent, :nested?
7
7
  end
8
8
 
9
9
  protected
@@ -24,28 +24,20 @@ module SuperResources
24
24
  controller_name.to_sym
25
25
  end
26
26
 
27
- def collection(&block)
28
- if block_given?
29
- @collection = yield
30
- else
31
- @collection ||= resource_class.scoped
32
- end
27
+ def collection
28
+ memoize_collection { resource_class.scoped }
33
29
  end
34
30
 
35
- def collection=(c)
36
- @collection = c
31
+ def memoize_collection(&block)
32
+ @collection ||= block.call
37
33
  end
38
34
 
39
- def resource(&block)
40
- if block_given?
41
- @resource = yield
42
- else
43
- @resource ||= resource_class.send(finder_method, params[:id])
44
- end
35
+ def resource
36
+ memoize_resource { resource_class.send(finder_method, params[:id]) }
45
37
  end
46
38
 
47
- def resource=(r)
48
- @resource = r
39
+ def memoize_resource(&block)
40
+ @resource ||= block.call
49
41
  end
50
42
 
51
43
  def finder_method
@@ -60,25 +52,20 @@ module SuperResources
60
52
  nil
61
53
  end
62
54
 
63
- def build_resource(&block)
64
- if block_given?
65
- @resource = yield
66
- else
67
- @resource ||= resource_class.new(resource_params)
68
- end
55
+ def resource_params
56
+ params[resource_params_name] || {}
69
57
  end
70
58
 
71
- def create_resource(attributes)
72
- build_resource.attributes = attributes
73
- resource.save
59
+ def build_resource(params={})
60
+ memoize_resource { resource_class.new(params) }
74
61
  end
75
62
 
76
- def update_resource(attributes)
77
- resource.update_attributes(attributes)
63
+ def create_resource(params)
64
+ build_resource(params).save
78
65
  end
79
-
80
- def resource_params
81
- params[resource_params_name] || {}
66
+
67
+ def update_resource(params)
68
+ resource.update_attributes(params)
82
69
  end
83
70
 
84
71
  def destroy_resource
@@ -0,0 +1,40 @@
1
+ module SuperResources
2
+ module Routing
3
+ extend ActiveSupport::Concern
4
+
5
+ protected
6
+
7
+ def routes
8
+ Rails.application.routes || request.env['action_dispatch.routes']
9
+ end
10
+
11
+ def router
12
+ routes.router
13
+ end
14
+
15
+ def route
16
+ @route ||= recognize_route(request.path.present? ? request : mock_request)
17
+ end
18
+
19
+ private
20
+
21
+ def recognize_route(request)
22
+ router.recognize(request) do |route, matches, params|
23
+ return route
24
+ end
25
+ end
26
+
27
+ def path_parameters
28
+ request.env['action_dispatch.request.path_parameters'].symbolize_keys
29
+ end
30
+
31
+ def mock_request
32
+ # used when there's no path in +request+. only seems to happen when
33
+ # testing controller actions
34
+ @mock_request ||= begin
35
+ env = Rack::MockRequest.env_for(url_for(path_parameters), :method => request.method)
36
+ request.class.new(env)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,46 @@
1
+ module SuperController
2
+ module Cancan
3
+ extend ActiveSupport::Concern
4
+
5
+ def index(*args)
6
+ authorize! :index, resource_class
7
+ super
8
+ end
9
+
10
+ def show(*args)
11
+ authorize! :show, resource
12
+ super
13
+ end
14
+
15
+ def new(*args)
16
+ authorize! :new, resource_class
17
+ super
18
+ end
19
+
20
+ def edit(*args)
21
+ authorize! :edit, resource
22
+ super
23
+ end
24
+
25
+ def create(*args)
26
+ authorize! :create, resource_class
27
+ super
28
+ end
29
+
30
+ def update(*args)
31
+ authorize! :update, resource
32
+ super
33
+ end
34
+
35
+ def destroy(*args)
36
+ authorize! :destroy, resource
37
+ super
38
+ end
39
+
40
+ protected
41
+
42
+ def collection
43
+ super.accessible_by(current_ability)
44
+ end
45
+ end
46
+ end
@@ -1,3 +1,3 @@
1
1
  module SuperResources
2
- VERSION = "1.0.0.rc1"
2
+ VERSION = "1.0.0.rc2"
3
3
  end
@@ -1,11 +1,18 @@
1
1
  module SuperResources
2
- autoload :Actions, "super_resources/actions"
3
- autoload :Controller, "super_resources/controller"
4
- autoload :Nesting, "super_resources/nesting"
5
- autoload :Resources, "super_resources/resources"
6
- autoload :URLHelpers, "super_resources/url_helpers"
7
- autoload :Version, "super_resources/version"
2
+ extend ActiveSupport::Autoload
8
3
 
9
- autoload :HasScope, "super_resources/has_scope"
10
- autoload :Cancan, "super_resources/cancan"
4
+ autoload :Actions
5
+ autoload :Controller
6
+ autoload :Nesting
7
+ autoload :Resources
8
+ autoload :Routing
9
+ autoload :URLHelpers
10
+ autoload :Version
11
+
12
+ autoload_under 'support' do
13
+ autoload :HasScope
14
+ autoload :Cancan
15
+ end
11
16
  end
17
+
18
+ require 'super_resources/railtie' if defined?(Rails)
@@ -10,8 +10,8 @@ class AdaptedResourcesController < SimpleResourcesController
10
10
  :input
11
11
  end
12
12
 
13
- def build_resource
14
- super do
13
+ def build_resource(params={})
14
+ memoize_resource do
15
15
  resource_class.new do |p|
16
16
  p.description = a_hard_coded_description
17
17
  end
@@ -1,6 +1,6 @@
1
1
  class GreatGrandparentResourcesController < ApplicationController
2
2
  def index
3
- super do
3
+ super.tap do
4
4
  collection.each do |r|
5
5
  r.description = 'We are all great grandparents'
6
6
  r.save
@@ -9,37 +9,37 @@ class GreatGrandparentResourcesController < ApplicationController
9
9
  end
10
10
 
11
11
  def show
12
- super do
12
+ super.tap do
13
13
  resource.description = 'I am a great grandparent'
14
14
  end
15
15
  end
16
16
 
17
17
  def new
18
- super do
18
+ super.tap do
19
19
  resource.description = 'I am becoming a new great grandparent'
20
20
  end
21
21
  end
22
22
 
23
23
  def edit
24
- super do
24
+ super.tap do
25
25
  resource.description = 'I am becoming a great grandparent again'
26
26
  end
27
27
  end
28
28
 
29
29
  def create
30
- super do
30
+ super.tap do
31
31
  resource.description = 'I am a new great grandparent'
32
32
  end
33
33
  end
34
34
 
35
35
  def update
36
- super do
36
+ super.tap do
37
37
  resource.description = 'I am a great grandparent again'
38
38
  end
39
39
  end
40
40
 
41
41
  def destroy
42
- super do
42
+ super.tap do
43
43
  @obituary = 'Here lies a dead great grandparent'
44
44
  end
45
45
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: super_resources
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc1
4
+ version: 1.0.0.rc2
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-02-05 00:00:00.000000000 Z
13
+ date: 2013-02-11 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: railties
@@ -36,19 +36,22 @@ executables: []
36
36
  extensions: []
37
37
  extra_rdoc_files: []
38
38
  files:
39
- - .DS_Store
40
39
  - .gitignore
41
40
  - Gemfile
42
41
  - LICENSE.txt
43
42
  - README.md
44
43
  - Rakefile
44
+ - lib/generators/rails/super_controller_generator.rb
45
+ - lib/generators/rails/templates/controller.rb
45
46
  - lib/super_resources.rb
46
47
  - lib/super_resources/actions.rb
47
- - lib/super_resources/cancan.rb
48
48
  - lib/super_resources/controller.rb
49
- - lib/super_resources/has_scope.rb
50
49
  - lib/super_resources/nesting.rb
50
+ - lib/super_resources/railtie.rb
51
51
  - lib/super_resources/resources.rb
52
+ - lib/super_resources/routing.rb
53
+ - lib/super_resources/support/cancan.rb
54
+ - lib/super_resources/support/has_scope.rb
52
55
  - lib/super_resources/url_helpers.rb
53
56
  - lib/super_resources/version.rb
54
57
  - spec/controllers/actions_nested_spec.rb
@@ -59,7 +62,6 @@ files:
59
62
  - spec/controllers/resources_adapted_spec.rb
60
63
  - spec/controllers/resources_nested_spec.rb
61
64
  - spec/controllers/resources_spec.rb
62
- - spec/dummy/.DS_Store
63
65
  - spec/dummy/README.rdoc
64
66
  - spec/dummy/Rakefile
65
67
  - spec/dummy/app/assets/javascripts/application.js
@@ -146,7 +148,6 @@ test_files:
146
148
  - spec/controllers/resources_adapted_spec.rb
147
149
  - spec/controllers/resources_nested_spec.rb
148
150
  - spec/controllers/resources_spec.rb
149
- - spec/dummy/.DS_Store
150
151
  - spec/dummy/README.rdoc
151
152
  - spec/dummy/Rakefile
152
153
  - spec/dummy/app/assets/javascripts/application.js
data/.DS_Store DELETED
Binary file
@@ -1,15 +0,0 @@
1
- module SuperController
2
- module Cancan
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- before_filter :authorize_resource
7
- end
8
-
9
- protected
10
-
11
- def authorize_resource
12
- #authorize! action_name.to_sym, resource
13
- end
14
- end
15
- end
data/spec/dummy/.DS_Store DELETED
Binary file