basic_assumption 0.3.5 → 0.3.6
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.
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
|
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
|
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
|
-
|
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
|
@@ -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
|
-
-
|
9
|
-
version: 0.3.
|
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-
|
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
|