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
|
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
|