basic_assumption 0.3.7 → 0.3.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,8 +1,11 @@
1
1
  == BasicAssumption
2
2
 
3
- A clone of DecentExposure with a psuedo-modular interface for providing
4
- custom defaults. It provides a declarative interface for specifying helper
5
- methods that is useful in Rails applications.
3
+ BasicAssumption is a gem meant to let you declare resources inside of a class
4
+ in a concise manner. It is targetted at making Rails controllers and views
5
+ cleaner.
6
+
7
+ It is a clone of DecentExposure that adds a psuedo-modular interface for
8
+ providing custom defaults and some useful defaults out of the box.
6
9
 
7
10
  === What is DecentExposure?
8
11
 
@@ -10,12 +13,10 @@ It's a plugin written by {Stephen Caudill}[http://voxdolo.me/] that provides a w
10
13
  cleaning up Rails controller and view code. Find it at
11
14
  {its GitHub repository}[http://github.com/voxdolo/decent_exposure].
12
15
 
13
- It represents an idiom for writing certain kinds of code in a declarative way.
14
- Particularly in your Rails apps, it's worth checking out. BasicAssumption is
15
- another implementation of the idiom. It exists largely because I felt like
16
- practicing writing a gem, though it does have a differentiating feature or two.
17
- Check the BasicAssumption::Configuration options for enabling compatibility
18
- with the DecentExposure API.
16
+ DecentExposure coins an idiom for writing certain kinds of code in a declarative
17
+ way. Particularly for your Rails apps, it's worth checking out. BasicAssumption
18
+ is another implementation of the idiom. Check the BasicAssumption::Configuration
19
+ options for enabling compatibility with the DecentExposure API.
19
20
 
20
21
  == Install BasicAssumption
21
22
 
@@ -84,8 +85,39 @@ And then inside of the 'widgets/purchase_complete.html.haml' view:
84
85
  %td= widget.manufacturer
85
86
 
86
87
  By calling +assume+ with the symbol :widget and passing it a block, an instance
87
- method is created on the controller class that is also exposed as a helper
88
- inside views. For more details on how BasicAssumption is wired into your Rails
88
+ method +widget+ is created on the controller that is also exposed as a helper
89
+ inside views.
90
+
91
+ ==== Special cases in controllers
92
+
93
+ A named resource created with +assume+ may be used in multiple controller
94
+ actions, or the same view template or partial referencing the named
95
+ resource may be rendered by more than one action. There will be times when
96
+ the behavior given to +assume+ is correct for most cases save one or two. It's
97
+ possible to override the value of the resource method within a particular
98
+ action to accommodate an exceptional case more easily. For example:
99
+
100
+ class WidgetController < ActionController::Base
101
+ assume :widget
102
+
103
+ def show
104
+ end
105
+
106
+ def show_mine
107
+ self.widget = current_user.widgets.find(params[:widget_id])
108
+ render :action => 'show'
109
+ end
110
+
111
+ def destroy
112
+ widget.destroy if widget.owned_by? current_user
113
+ end
114
+ end
115
+
116
+ In this case, the +show_mine+ action overrides the value of widget so that it
117
+ may reuse the view template for the regular +show+ action. Overriding the
118
+ assumed resource should be the exception, not the rule.
119
+
120
+ For more details on how BasicAssumption is wired into your Rails
89
121
  app, please see the BasicAssumption::Railtie documentation.
90
122
 
91
123
  === When to use it
@@ -115,47 +147,78 @@ would become this:
115
147
  assume :record
116
148
  end
117
149
 
118
- and would have the added benefit of not tossing instance variables around.
150
+ and would provide the added benefit of not tossing instance variables around.
119
151
  If a controller has protected or hidden methods that find or create instance
120
152
  variables used in actions and/or views, it might be cleaner to use an
121
- assumption instead.
153
+ assumption instead. This:
154
+
155
+ class CompanyController < ActionController::Base
156
+
157
+ def show
158
+ @company = Company.find(params[:company_id])
159
+ end
160
+
161
+ def unique_groups
162
+ @unique_groups = Group.unique_groups(@company)
163
+ end
164
+ helper_method :unique_groups
165
+ hide_action :unique_groups
166
+
167
+ end
168
+
169
+ could instead be written as:
170
+
171
+ class CompanyController < ActionController::Base
172
+
173
+ assume :company
174
+ assume(:unique_groups) { Group.unique_groups(company) }
175
+
176
+ end
122
177
 
123
178
  BasicAssumption allows for a simple, declarative, and very lightweight approach
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.
179
+ to RESTful controllers. It also tends to make for a cleaner, more testable
180
+ interface for controller or view testing. There may even be uses outside of
181
+ Rails apps. Give it a shot.
127
182
 
128
- === Defaults
183
+ == Defaults
129
184
 
130
185
  BasicAssumption allows for default behavior to be associated with methods
131
186
  created by +assume+ whenever a block is not passed. Here is a simple example:
132
187
 
133
- class WidgetController < ActionController::Base
134
- default_assumption { Widget.find(params[:id]) }
135
- assume(:widget)
188
+ class MariosController < ActionController::Base
189
+ default_assumption { "It's a me, Mario!" }
190
+ assume :mario
136
191
 
137
192
  ...
138
193
  end
139
194
 
140
- This will provide the same behavior as the similar example above. It is also
141
- possible to pass a proc or lambda directly.
195
+ MariosController.new.mario #=> 'It's a me, Mario!'
142
196
 
143
- Finally, a symbol may be passed if it corresponds to a
144
- specifically-defined helper class that came packaged with the library or was
145
- provided by the application.
197
+ In this case, any calls to +assume+ that don't provide a block will create
198
+ methods that return the string "It's a me, Mario!".
199
+
200
+ In addition to passing a default block, a symbol may be passed if it corresponds
201
+ to a specifically-defined helper class that came packaged with the
202
+ BasicAssumption library or was provided by the application as a custom default.
203
+ See below for more information on providing custom defaults.
204
+
205
+ Specifying a built-in or application-defined default can be done on +assume+
206
+ calls as well.
207
+
208
+ assume :luigi, :using => :luigi_strategy
146
209
 
147
210
  === In Rails
148
211
 
149
212
  In Rails, a useful default is already active out of the box. It attempts to
150
- guess the name of a class derived from ActiveRecord::Base and do a find on it
151
- based on an id available in the +params+ of the request. Because of this, the
213
+ guess the name of a class derived from ActiveRecord::Base and perform a find on
214
+ it based on an id available in the +params+ of the request. Because of this, the
152
215
  following two constructs would be equivalent in your controllers:
153
216
 
154
217
  assume(:film) { Film.find(params[:film_id] || params[:id]) }
155
218
  # The above line is exactly the same as:
156
219
  assume(:film)
157
220
 
158
- Please see +SimpleRails+ for details of implementation. Because finding on :id
221
+ Please see +Rails+ for implementation details . Because finding on :id
159
222
  could be considered dangerous, there is another default available for use,
160
223
  +CautiousRails+, that will only find on :name_id. (In the example above,
161
224
  this would be :film_id.) Enable that for one of your controllers like so:
@@ -170,27 +233,64 @@ description of how it works.
170
233
 
171
234
  Default assumptions are inherited by derived classes.
172
235
 
173
- === Supplying custom default behavior classes
236
+ == Supplying custom default behavior classes
174
237
 
175
238
  There is an ability to provide custom, modular default extensions to
176
239
  BasicAssumption and then use them by passing a symbol, as in the following:
177
240
 
178
241
  class WidgetController < ActionController::Base
179
- default_assumption :my_custom_default_class
242
+ default_assumption :my_custom_rails_default
243
+ end
244
+
245
+ The symbol is converted to a class in the same manner as Rails
246
+ classify/constantize operates, but it is looked up in the
247
+ BasicAssumption::DefaultAssumption namespace. The following code implements the
248
+ custom default specified in the preceding example. It reimplements the behavior
249
+ that is active by default within Rails.
250
+
251
+ module BasicAssumption
252
+ module DefaultAssumption
253
+ class MyCustomRailsDefault
254
+
255
+ def initialize(name=nil, params={})
256
+ @name = name.to_s
257
+ @lookup = params['id']
258
+ end
259
+
260
+ def block
261
+ klass = self.class
262
+ Proc.new do |name|
263
+ klass.new(name, params).result
264
+ end
265
+ end
266
+
267
+ def result
268
+ model_class.find(@lookup)
269
+ end
270
+
271
+ # Rely on ActiveSupport methods
272
+ def model_class
273
+ name.classify.constantize
274
+ end
275
+ end
276
+ end
180
277
  end
181
278
 
182
- The symbol is converted to a class in the same manner as Rails classify/
183
- constantize operates, but it is looked up in the
184
- BasicAssumption::DefaultAssumption namespace. Please see the documentation for
185
- +DefaultAssumption+ for a discussion and +SimpleRails+ for an example of this.
279
+ The only method that BasicAssumption depends on in the interface of custom
280
+ default classes is the +block+ method. Note the hoops that have to be jumped
281
+ through inside the implementation of +block+ in this example. Keep in mind the
282
+ implications of evaluating the +Proc+ returned by +block+ using +instance_eval+
283
+ (or +instance_exec+).
186
284
 
187
- === Configuration
285
+ == Configuration
188
286
 
189
- There are a couple of simple configuration settings that can be set inside of
287
+ There are a couple of configuration settings that can be set inside of
190
288
  a configuration block that can be used in places such as Rails initializer
191
- blocks. For more information, see BasicAssumption::Configuration.
289
+ blocks. #emulate_exposure! will alias +assume+ and +default_assumption+ to
290
+ +expose+ and +default_exposure+, respectively. You can also set the app-wide
291
+ default behavior. For more information, see BasicAssumption::Configuration.
192
292
 
193
- == Issues
293
+ == Issues to note
194
294
 
195
295
  === Memoization
196
296
 
@@ -208,30 +308,24 @@ be observed.
208
308
  Using BasicAssumption may change the exception handling strategy inside your
209
309
  classes. In Rails, the +rescue_from+ method may be useful.
210
310
 
211
- === Other
212
-
213
- There are probably others, and when I remember what they were, I'll write them
214
- up.
215
-
216
311
  == Hacking/running specs
217
312
 
218
313
  There is nothing special about running the specs, aside from ensuring the
219
314
  RUBYOPT environment variable is set to your preferred Ruby dependency
220
- manager. For example, if RubyGems:
315
+ manager. For example, if that's RubyGems:
221
316
 
222
317
  export RUBYOPT=rubygems
223
318
 
224
319
  If you're unfamiliar with why this is being done, take a look
225
320
  {here for a start}[http://tomayko.com/writings/require-rubygems-antipattern].
226
- Other than that, please feel free to fork and send back pull requests! Thanks.
321
+ Other than that, fork away and send back pull requests! Thanks.
227
322
 
228
323
  == But should I use it?
229
324
 
230
325
  Sure! Absolutely. I think it's a cool idea that lets you cut down on line
231
326
  noise, particularly in your Rails controllers. You may want to consider going
232
- with {DecentExposure}[http://github.com/voxdolo/decent_exposure], simply
233
- because it's used by much of {Hashrocket}[http://www.hashrocket.com/]
234
- and BasicAssumption is used, so far as I know, only by me. But so far as I know
235
- BasicAssumption is pretty solid, and I'm happy to accept bug fixes and field
236
- feature requests. If you use it, feel free to let me know! Email mby [at]
237
- mattyoho [dot] com with questions, comments, or non-sequiters.
327
+ with {DecentExposure}[http://github.com/voxdolo/decent_exposure] instead, simply
328
+ because it's used by much of {Hashrocket}[http://www.hashrocket.com/].
329
+ But so far as I know, BasicAssumption is pretty solid. Feel free to let me know
330
+ if you use it! Email mby [at] mattyoho [dot] com with questions, comments, or
331
+ non-sequiters.
@@ -67,7 +67,7 @@ module BasicAssumption
67
67
  @basic_assumptions[name] ||= if block_given?
68
68
  instance_eval(&block)
69
69
  else
70
- which = strategy[:with] || self.class
70
+ which = strategy[:using] || self.class
71
71
  block = DefaultAssumption.resolve(which)
72
72
  instance_exec(name, &block)
73
73
  end
@@ -18,15 +18,15 @@ module BasicAssumption
18
18
  #
19
19
  # It is possible to pass a symbol instead of a block to the
20
20
  # +default_assumption+ call. BasicAssumption out of the box will understand
21
- # the symbol :simple_rails as an option passed to +default_assumption+,
21
+ # the symbol :rails as an option passed to +default_assumption+,
22
22
  # and will use the block provided by an instance of
23
- # BasicAssumption::DefaultAssumption::SimpleRails as the default behavior.
23
+ # BasicAssumption::DefaultAssumption::Rails as the default behavior.
24
24
  #
25
25
  # BasicAssumption will use the same process for any symbol passed to
26
26
  # +default_assumption+. If you pass it :my_custom_default it will attempt
27
27
  # to find a class BasicAssumption::DefaultAssumption::MyCustomDefault that
28
28
  # provides a +block+ instance method, and use the result as the default
29
- # behavior. See the +SimpleRails+ class for an example.
29
+ # behavior. See the +Rails+ class for an example.
30
30
  module DefaultAssumption
31
31
  def self.register(klass, default) #:nodoc:
32
32
  registry[klass.object_id] = strategy(default)
@@ -1,7 +1,9 @@
1
+ require 'basic_assumption/default_assumption/rails'
2
+
1
3
  module BasicAssumption
2
4
  module DefaultAssumption
3
5
  # Custom default behavior in the context of Rails.
4
- class CautiousRails < BasicAssumption::DefaultAssumption::Base
6
+ class CautiousRails < BasicAssumption::DefaultAssumption::Rails
5
7
  # Returns a block that will attempt to find an instance of
6
8
  # an ActiveRecord model based on the name that was given to
7
9
  # BasicAssumption#assume and an id value in the parameters.
@@ -16,10 +18,12 @@ module BasicAssumption
16
18
  # assume(:widget) { Widget.find(params[:widget_id]) }
17
19
  # end
18
20
  def block
19
- Proc.new do |name|
20
- model_class = name.to_s.classify.constantize
21
- model_class.find(params["#{name}_id"])
22
- end
21
+ super
22
+ end
23
+
24
+ protected
25
+ def lookup_id #:nodoc:
26
+ params["#{name}_id"]
23
27
  end
24
28
  end
25
29
  end
@@ -1,2 +1,43 @@
1
- require 'basic_assumption/default_assumption/simple_rails'
1
+ module BasicAssumption
2
+ module DefaultAssumption
3
+ # Custom default behavior in the context of Rails.
4
+ class Rails < BasicAssumption::DefaultAssumption::Base
5
+ attr_reader :name, :params #:nodoc:
2
6
 
7
+ def initialize(name=nil, params={}) #:nodoc:
8
+ @name, @params = name.to_s, params
9
+ end
10
+ # Returns a block that will attempt to find an instance of
11
+ # an ActiveRecord model based on the name that was given to
12
+ # BasicAssumption#assume and an id value in the parameters.
13
+ # The following two examples would be equivalent:
14
+ #
15
+ # class WidgetController < ActionController::Base
16
+ # assume :widget
17
+ # end
18
+ #
19
+ # class WidgetController < ActionController::Base
20
+ # assume(:widget) { Widget.find(params[:widget_id] || params[:id]) }
21
+ # end
22
+ def block
23
+ klass = self.class
24
+ Proc.new do |name|
25
+ klass.new(name, params).result
26
+ end
27
+ end
28
+
29
+ def result #:nodoc:
30
+ model_class.find(lookup_id)
31
+ end
32
+
33
+ protected
34
+ def lookup_id #:nodoc:
35
+ params["#{name}_id"] || params['id']
36
+ end
37
+
38
+ def model_class #:nodoc:
39
+ @model_class ||= name.classify.constantize
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,20 +1,17 @@
1
+ require 'basic_assumption/default_assumption/rails'
2
+
1
3
  module BasicAssumption
2
4
  module DefaultAssumption
3
5
  # Restful default behavior in the context of Rails
4
- class RestfulRails < BasicAssumption::DefaultAssumption::Base
6
+ class RestfulRails < BasicAssumption::DefaultAssumption::Rails
5
7
  attr_reader :action,
6
- :lookup_id,
7
- :name,
8
8
  :page,
9
- :params,
10
9
  :per_page,
11
10
  :resource_attributes #:nodoc:
12
11
 
13
12
  def initialize(name = nil, params = {}) #:nodoc:
13
+ super
14
14
  @action = params['action']
15
- @lookup_id = params['id']
16
- @name = name.to_s
17
- @params = params
18
15
  @resource_attributes = params[singular_name]
19
16
 
20
17
  if @page = params['page']
@@ -52,10 +49,7 @@ module BasicAssumption
52
49
  # results, also observing a +per_page+ value in the +params+ hash or
53
50
  # defaulting to 15 if one is not found.
54
51
  def block
55
- klass = self.class
56
- Proc.new do |name|
57
- klass.new(name, params).result
58
- end
52
+ super
59
53
  end
60
54
 
61
55
  def result #:nodoc:
@@ -86,16 +80,16 @@ module BasicAssumption
86
80
  action.eql?('index') && plural_name.eql?(name)
87
81
  end
88
82
 
89
- def lookup?
90
- params['id'].present?
83
+ def lookup_id #:nodoc:
84
+ params['id']
91
85
  end
92
86
 
93
- def make? #:nodoc:
94
- %w(new create).include?(action) || !lookup?
87
+ def lookup? #:nodoc:
88
+ lookup_id.present?
95
89
  end
96
90
 
97
- def model_class #:nodoc:
98
- @model_class ||= name.classify.constantize
91
+ def make? #:nodoc:
92
+ %w(new create).include?(action) || !lookup?
99
93
  end
100
94
 
101
95
  def page? #:nodoc:
@@ -4,7 +4,7 @@ if defined?(Rails) && Rails::VERSION::MAJOR == 3
4
4
  module BasicAssumption
5
5
  # Must be required explicitly in Rails 3. Extends ActionController::Base
6
6
  # with BasicAssumption, sets the default assumption behavior to be the
7
- # :simple_rails behavior, and sets up an +after_assumption+ hook.
7
+ # :rails behavior, and sets up an +after_assumption+ hook.
8
8
  class Railtie < Rails::Railtie
9
9
 
10
10
  initializer "basic_assumption.set_up_action_controller_base" do |app|
@@ -21,7 +21,7 @@ if defined?(Rails) && Rails::VERSION::MAJOR == 3
21
21
  end
22
22
 
23
23
  BasicAssumption::Configuration.configure do |config|
24
- config.default_assumption = :simple_rails
24
+ config.default_assumption = :rails
25
25
  end
26
26
  end
27
27
  end
@@ -1,3 +1,3 @@
1
1
  module BasicAssumption
2
- VERSION = '0.3.7'
2
+ VERSION = '0.3.8'
3
3
  end
@@ -11,5 +11,5 @@ ActionController::Base.class_eval do
11
11
  end
12
12
 
13
13
  BasicAssumption::Configuration.configure do |config|
14
- config.default_assumption = :simple_rails
14
+ config.default_assumption = :rails
15
15
  end
@@ -1,12 +1,12 @@
1
1
  require 'spec_helper'
2
2
  require 'active_support'
3
- require 'basic_assumption/default_assumption/simple_rails'
3
+ require 'basic_assumption/default_assumption/rails'
4
4
 
5
- describe BasicAssumption::DefaultAssumption::SimpleRails do
5
+ describe BasicAssumption::DefaultAssumption::Rails do
6
6
  class Model; end
7
7
 
8
8
  context "#block" do
9
- let(:default) { BasicAssumption::DefaultAssumption::SimpleRails.new }
9
+ let(:default) { BasicAssumption::DefaultAssumption::Rails.new }
10
10
  let(:params) { stub(:[] => 42) }
11
11
 
12
12
  before(:each) do
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require 'lib/basic_assumption/default_assumption/simple_rails'
2
+ require 'lib/basic_assumption/default_assumption/rails'
3
3
 
4
4
  describe BasicAssumption::DefaultAssumption do
5
5
  let(:mod) { BasicAssumption::DefaultAssumption }
@@ -25,8 +25,8 @@ describe BasicAssumption::DefaultAssumption do
25
25
  mod.send(:strategy, a_proc).call.should eql(:block)
26
26
  end
27
27
  it "returns the block of a class in the BasicAssumption::DefaultAssumption namespace when given a symbol" do
28
- mod::SimpleRails.should_receive(:new).and_return(stub(:block => :block))
29
- mod.send(:strategy, :simple_rails).should eql(:block)
28
+ mod::Rails.should_receive(:new).and_return(stub(:block => :block))
29
+ mod.send(:strategy, :rails).should eql(:block)
30
30
  end
31
31
  it "returns the block of a Base instance otherwise" do
32
32
  mod.send(:strategy, nil).call.should be_nil
@@ -44,7 +44,7 @@ describe BasicAssumption do
44
44
  context "when a strategy is passed to #assume" do
45
45
  it "looks up the strategy from the existing defaults to provide the behavior of the instance method" do
46
46
  extender_class.class_eval do
47
- assume :looked_up, :with => :strategy
47
+ assume :looked_up, :using => :strategy
48
48
  end
49
49
  BasicAssumption::DefaultAssumption.should_receive(:resolve).with(:strategy).and_return(Proc.new {})
50
50
  extender_instance.looked_up
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 3
8
- - 7
9
- version: 0.3.7
8
+ - 8
9
+ version: 0.3.8
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-02 00:00:00 -05:00
17
+ date: 2010-06-04 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -79,7 +79,6 @@ files:
79
79
  - lib/basic_assumption/default_assumption/class_resolver.rb
80
80
  - lib/basic_assumption/default_assumption/rails.rb
81
81
  - lib/basic_assumption/default_assumption/restful_rails.rb
82
- - lib/basic_assumption/default_assumption/simple_rails.rb
83
82
  - lib/basic_assumption/rails.rb
84
83
  - lib/basic_assumption/version.rb
85
84
  - rails/init.rb
@@ -121,5 +120,5 @@ test_files:
121
120
  - spec/lib/basic_assumption/default_assumption/base_spec.rb
122
121
  - spec/lib/basic_assumption/default_assumption/cautious_rails_spec.rb
123
122
  - spec/lib/basic_assumption/default_assumption/class_resolver_spec.rb
123
+ - spec/lib/basic_assumption/default_assumption/rails_spec.rb
124
124
  - spec/lib/basic_assumption/default_assumption/restful_rails_spec.rb
125
- - spec/lib/basic_assumption/default_assumption/simple_rails_spec.rb
@@ -1,26 +0,0 @@
1
- module BasicAssumption
2
- module DefaultAssumption
3
- # Custom default behavior in the context of Rails.
4
- class SimpleRails < BasicAssumption::DefaultAssumption::Base
5
- # Returns a block that will attempt to find an instance of
6
- # an ActiveRecord model based on the name that was given to
7
- # BasicAssumption#assume and an id value in the parameters.
8
- # The following two examples would be equivalent:
9
- #
10
- # class WidgetController < ActionController::Base
11
- # assume :widget
12
- # end
13
- #
14
- # class WidgetController < ActionController::Base
15
- # assume(:widget) { Widget.find(params[:widget_id] || params[:id]) }
16
- # end
17
- def block
18
- Proc.new do |name|
19
- model_class = name.to_s.classify.constantize
20
- model_class.find(params["#{name}_id"] || params['id'])
21
- end
22
- end
23
- end
24
- end
25
- end
26
-