basic_assumption 0.3.5 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -6,7 +6,7 @@ methods that is useful in Rails applications.
6
6
 
7
7
  === What is DecentExposure?
8
8
 
9
- It's a plugin written by {Stephen Cuadill}[http://voxdolo.me/] that provides a way of
9
+ It's a plugin written by {Stephen Caudill}[http://voxdolo.me/] that provides a way of
10
10
  cleaning up Rails controller and view code. Find it at
11
11
  {its GitHub repository}[http://github.com/voxdolo/decent_exposure].
12
12
 
@@ -52,7 +52,7 @@ available inside your controllers.
52
52
  The most important (of the few) methods made available in controller classes is
53
53
  +assume+, which is used to declaratively define a resource of some kind in
54
54
  controller instances and to make that resource available inside corresponding
55
- views. For all the verbiage of the description, it's a simple concept, as
55
+ views. For all the wordiness of the description, it's a simple concept, as
56
56
  illustrated below. First, we will use +assume+ to expose a resource inside our
57
57
  controller actions that will take the value resulting from the block passed to
58
58
  +assume+. In this case, the resource will be called 'widget':
@@ -96,15 +96,34 @@ probably use an assumption instead. Because BasicAssumption is written to use
96
96
  lazy evaluation, there's no need to worry about avoiding calls on actions that
97
97
  don't need some particular setup.
98
98
 
99
+ For example, this:
100
+
101
+ class RecordController < ActionController::Base
102
+ before_filter :find_record, :only => [:show, :edit, :update, :destroy]
103
+
104
+ ...
105
+
106
+ protected
107
+ def find_record
108
+ @record = Record.find(params[:record_id] || params[:id])
109
+ end
110
+ end
111
+
112
+ would become this:
113
+
114
+ class RecordController < ActionController::Base
115
+ assume :record
116
+ end
117
+
118
+ and would have the added benefit of not tossing instance variables around.
99
119
  If a controller has protected or hidden methods that find or create instance
100
120
  variables used in actions and/or views, it might be cleaner to use an
101
121
  assumption instead.
102
122
 
103
123
  BasicAssumption allows for a simple, declarative, and very lightweight approach
104
- to RESTful controllers.
105
-
106
- It also can make for a cleaner, more testable interface for controller or view
107
- testing. There may even be uses outside of Rails apps. Give it a shot.
124
+ to RESTful controllers. It also can make for a cleaner, more testable interface
125
+ for controller or view testing. There may even be uses outside of Rails apps.
126
+ Give it a shot.
108
127
 
109
128
  === Defaults
110
129
 
@@ -145,6 +164,10 @@ this would be :film_id.) Enable that for one of your controllers like so:
145
164
  default_assumption :cautious_rails
146
165
  end
147
166
 
167
+ Another option is :restful_rails, which attempts to provide appropriate
168
+ behavior for the basic RESTful actions. Please see +RestfulRails+ for a
169
+ description of how it works.
170
+
148
171
  Default assumptions are inherited by derived classes.
149
172
 
150
173
  === Supplying custom default behavior classes
@@ -0,0 +1,114 @@
1
+ module BasicAssumption
2
+ module DefaultAssumption
3
+ # Restful default behavior in the context of Rails
4
+ class RestfulRails < BasicAssumption::DefaultAssumption::Base
5
+ attr_reader :action,
6
+ :lookup_id,
7
+ :name,
8
+ :page,
9
+ :params,
10
+ :per_page,
11
+ :resource_attributes #:nodoc:
12
+
13
+ def initialize(name = nil, params = {}) #:nodoc:
14
+ @action = params['action']
15
+ @lookup_id = params['id']
16
+ @name = name.to_s
17
+ @params = params
18
+ @resource_attributes = params[singular_name]
19
+
20
+ if @page = params['page']
21
+ @per_page = params['per_page'] || '15'
22
+ end
23
+ end
24
+
25
+ # Returns a block that will attempt to do the correct thing depending
26
+ # on which action the request is triggering. If the action is 'show',
27
+ # 'edit', 'update', or 'destroy', then +assume+ will find an instance of
28
+ # an ActiveRecord model based on the +name+ that it recieved and an id
29
+ # value in the parameters. If the action is 'new' or 'create', +assume+
30
+ # will instantiate a new instance of the model class, passing in the
31
+ # values it finds in the +params+ hash with a key of the singularized
32
+ # form of the +name+ passed to +assume+. For example:
33
+ #
34
+ # class WidgetController < ApplicationController
35
+ # default_assumption :restful_rails
36
+ # assume :widget
37
+ #
38
+ # def create
39
+ # widget.save! # widget is: Widget.new(params[:widget])
40
+ # end
41
+ # end
42
+ #
43
+ # Note the object will have been instantiated but not saved, destroyed,
44
+ # etc. If the action is 'index', there are two possibilities for the
45
+ # behavior of +assume+. If the +name+ passed is of singular form, then
46
+ # a find will be performed, just as for a show or edit action. If the
47
+ # +name+ is a plural word, then +assume+ will find all instances of
48
+ # the model class.
49
+ #
50
+ # However, if the model responds to +paginate+ and there is a +page+
51
+ # key in the +params+ hash, +assume+ will attempt to paginate the
52
+ # results, also observing a +per_page+ value in the +params+ hash or
53
+ # defaulting to 15 if one is not found.
54
+ def block
55
+ klass = self.class
56
+ Proc.new do |name|
57
+ klass.new(name, params).result
58
+ end
59
+ end
60
+
61
+ def result #:nodoc:
62
+ if list?
63
+ list
64
+ elsif make?
65
+ model_class.new(resource_attributes)
66
+ else
67
+ model_class.find(lookup_id)
68
+ end
69
+ end
70
+
71
+ protected
72
+
73
+ def find? #:nodoc:
74
+ %w(show edit update destroy).include? action
75
+ end
76
+
77
+ def list #:nodoc:
78
+ if page?
79
+ model_class.paginate('page' => page, 'per_page' => per_page)
80
+ else
81
+ model_class.all
82
+ end
83
+ end
84
+
85
+ def list? #:nodoc:
86
+ action.eql?('index') && plural_name.eql?(name)
87
+ end
88
+
89
+ def lookup?
90
+ params['id'].present?
91
+ end
92
+
93
+ def make? #:nodoc:
94
+ %w(new create).include?(action) || !lookup?
95
+ end
96
+
97
+ def model_class #:nodoc:
98
+ @model_class ||= name.classify.constantize
99
+ end
100
+
101
+ def page? #:nodoc:
102
+ page.present? && model_class.respond_to?(:paginate)
103
+ end
104
+
105
+ def plural_name #:nodoc:
106
+ name.pluralize
107
+ end
108
+
109
+ def singular_name #:nodoc:
110
+ name.singularize
111
+ end
112
+ end
113
+ end
114
+ end
@@ -1,3 +1,3 @@
1
1
  module BasicAssumption
2
- VERSION = '0.3.5'
2
+ VERSION = '0.3.6'
3
3
  end
@@ -0,0 +1,160 @@
1
+ require 'spec_helper'
2
+ require 'active_support'
3
+ require 'basic_assumption/default_assumption/restful_rails'
4
+
5
+ describe BasicAssumption::DefaultAssumption::RestfulRails do
6
+ class Model
7
+ attr_accessor :age, :color
8
+ def initialize(hash = {})
9
+ hash.each do |k, v|
10
+ self.send("#{k}=", v)
11
+ end
12
+ end
13
+ end
14
+
15
+ it { should be }
16
+
17
+ context "#block" do
18
+ let(:default) { BasicAssumption::DefaultAssumption::RestfulRails.new(:model, params) }
19
+
20
+ before(:each) do
21
+ Model.stub!(:find)
22
+ default.stub!(:params).and_return(params)
23
+ end
24
+
25
+ context "in the show action" do
26
+ let(:params) { { 'id' => 42, 'action' => 'show' } }
27
+
28
+ it "attempts to find a model instance based off the given name" do
29
+ Model.should_receive(:find).with(42).and_return(:model)
30
+ default.block.call(:model).should eql(:model)
31
+ end
32
+ end
33
+
34
+ context "in the edit action" do
35
+ let(:params) { { 'id' => 42, 'action' => 'edit' } }
36
+
37
+ it "attempts to find a model instance based off the given name" do
38
+ Model.should_receive(:find).with(42).and_return(:model)
39
+ default.block.call(:model).should eql(:model)
40
+ end
41
+ end
42
+
43
+ context "in the update action" do
44
+ let(:params) do
45
+ { 'id' => 42 }
46
+ end
47
+
48
+ it "attempts to find a model instance based off the given name" do
49
+ Model.should_receive(:find).with(42).and_return(:model)
50
+ default.block.call(:model).should eql(:model)
51
+ end
52
+ end
53
+
54
+ context "in the destroy action" do
55
+ let(:params) { { 'id' => 42, 'action' => 'destroy' } }
56
+
57
+ it "attempts to find a model instance based off the given name" do
58
+ Model.should_receive(:find).with(42).and_return(:model)
59
+ default.block.call(:model).should eql(:model)
60
+ end
61
+ end
62
+
63
+ context "in the create action" do
64
+ let(:params) do
65
+ {
66
+ 'action' => 'create',
67
+ 'model' => { 'age' => 27, 'color' => 'blue' }
68
+ }
69
+ end
70
+
71
+ context "the model instance" do
72
+ subject { default.block.call(:model) }
73
+ its(:age) { should be(27) }
74
+ its(:color) { should eql('blue') }
75
+ end
76
+ end
77
+
78
+ context "in the new action" do
79
+ let(:params) do
80
+ {
81
+ 'action' => 'new',
82
+ 'model' => { 'age' => 27, 'color' => 'blue' }
83
+ }
84
+ end
85
+
86
+ context "the model instance" do
87
+ subject { default.block.call(:model) }
88
+ its(:age) { should be(27) }
89
+ its(:color) { should eql('blue') }
90
+ end
91
+ end
92
+
93
+ context "in the index action" do
94
+ let(:params) { { 'action' => 'index' } }
95
+ context "when the name given to assume is plural" do
96
+ let(:name) { :models }
97
+ context "without pagination" do
98
+ before { Model.should_receive(:all) }
99
+ context "when 'page' exists in the request params" do
100
+ before { params['page'] = '5' }
101
+ it "finds all the records of the model class" do
102
+ default.block.call(name)
103
+ end
104
+ end
105
+ context "when 'page' does not exist in the request params" do
106
+ it "finds all the records of the model class" do
107
+ default.block.call(name)
108
+ end
109
+ end
110
+ end
111
+ context "with pagination" do
112
+ before { Model.stub! :paginate }
113
+ context "when 'page' exists in the request params" do
114
+ before { params['page'] = '5' }
115
+ it "paginates the records of the model class" do
116
+ Model.should_receive(:paginate)
117
+ default.block.call(name)
118
+ end
119
+ context "when 'per_page' exists in the request params" do
120
+ it "paginates using 'page' and 'per_page' from the params" do
121
+ params['per_page'] = '10'
122
+ Model.should_receive(:paginate).with('page' => '5', 'per_page' => '10')
123
+ default.block.call(name)
124
+ end
125
+ end
126
+ context "when 'per_page' does not exist in the request params" do
127
+ it "paginates using 'page' from the params and a default 'per_page' of 15" do
128
+ Model.should_receive(:paginate).with('page' => '5', 'per_page' => '15')
129
+ default.block.call(name)
130
+ end
131
+ end
132
+ end
133
+ context "when 'page' does not exist in the request params" do
134
+ it "finds all the records of the model class" do
135
+ Model.should_receive(:all)
136
+ default.block.call(name)
137
+ end
138
+ end
139
+ end
140
+ end
141
+ context "when the name given to assume is singular" do
142
+ let(:name) { :model }
143
+ context "and there is an id in params" do
144
+ before { params['id'] = 1 }
145
+ it "attempts to find a model instance based off the given name" do
146
+ Model.should_receive(:find).with(1).and_return(:model)
147
+ default.block.call(name).should eql(:model)
148
+ end
149
+ end
150
+ context "and there is no id in params" do
151
+ before { params['model'] = :initializers }
152
+ it "creates a new model instance and passes in appropriate params" do
153
+ Model.should_receive(:new).with(:initializers).and_return(:model)
154
+ default.block.call(name).should eql(:model)
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 3
8
- - 5
9
- version: 0.3.5
8
+ - 6
9
+ version: 0.3.6
10
10
  platform: ruby
11
11
  authors:
12
12
  - Matt Yoho
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-26 00:00:00 -05:00
17
+ date: 2010-05-27 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -78,6 +78,7 @@ files:
78
78
  - lib/basic_assumption/default_assumption/cautious_rails.rb
79
79
  - lib/basic_assumption/default_assumption/class_resolver.rb
80
80
  - lib/basic_assumption/default_assumption/rails.rb
81
+ - lib/basic_assumption/default_assumption/restful_rails.rb
81
82
  - lib/basic_assumption/default_assumption/simple_rails.rb
82
83
  - lib/basic_assumption/rails.rb
83
84
  - lib/basic_assumption/version.rb
@@ -120,4 +121,5 @@ test_files:
120
121
  - spec/lib/basic_assumption/default_assumption/base_spec.rb
121
122
  - spec/lib/basic_assumption/default_assumption/cautious_rails_spec.rb
122
123
  - spec/lib/basic_assumption/default_assumption/class_resolver_spec.rb
124
+ - spec/lib/basic_assumption/default_assumption/restful_rails_spec.rb
123
125
  - spec/lib/basic_assumption/default_assumption/simple_rails_spec.rb