response_for_rails 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/CHANGELOG +22 -0
- data/Gemfile +3 -0
- data/Gemfile.lock.development +109 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +126 -0
- data/Rakefile +32 -0
- data/lib/response_for/action_controller.rb +151 -0
- data/lib/response_for/railtie.rb +9 -0
- data/lib/response_for/responses_module.rb +47 -0
- data/lib/response_for/version.rb +3 -0
- data/lib/response_for.rb +7 -0
- data/lib/response_for_rails.rb +7 -0
- data/response_for.gemspec +30 -0
- data/spec/app/database.yml +5 -0
- data/spec/app/views/error_in_template_spec/test/error_in_template.html.erb +1 -0
- data/spec/app/views/inherited_controller_spec/super/a_response.html.erb +0 -0
- data/spec/app/views/inherited_controller_spec/super/an_action.html.erb +0 -0
- data/spec/app/views/pick_template_spec/template_only/an_action.atom.erb +1 -0
- data/spec/app/views/pick_template_spec/template_only/an_action.html.erb +1 -0
- data/spec/app/views/pick_template_spec/template_only/an_action.js.erb +1 -0
- data/spec/app/views/pick_template_spec/template_only/an_action.xml.erb +1 -0
- data/spec/app/views/stop_at_respond_to_spec/test/index.atom.builder +1 -0
- data/spec/app/views/stop_at_respond_to_spec/test/index.html.erb +1 -0
- data/spec/controllers/default_rails_behaviour_spec.rb +48 -0
- data/spec/controllers/error_in_template_spec.rb +20 -0
- data/spec/controllers/inherited_controllers_spec.rb +137 -0
- data/spec/controllers/no_response_if_performed_spec.rb +40 -0
- data/spec/controllers/pick_template_spec.rb +159 -0
- data/spec/controllers/remove_response_for_spec.rb +34 -0
- data/spec/controllers/responses_module_spec.rb +38 -0
- data/spec/controllers/stacking_responses_spec.rb +125 -0
- data/spec/controllers/stop_at_respond_to_spec.rb +51 -0
- data/spec/spec_helper.rb +27 -0
- metadata +142 -0
data/CHANGELOG
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
* 0.4.0 - Gemified [Josh Goebel, Ian White]
|
2
|
+
* The gem is called `response_for_rails`, see related `rc_rails` and `response_for_rc_rails`
|
3
|
+
* Removed Ardes namespace
|
4
|
+
|
5
|
+
* 0.3.2 - Rails 3.1 compat
|
6
|
+
|
7
|
+
* 0.2.2 - Fixed bug where response_for would clobber a respond_to if if the respond_to relied on default render [thanks Tom Stuart for the bug report]
|
8
|
+
|
9
|
+
* Added VERSION introspection, this is 0.2.1
|
10
|
+
|
11
|
+
* To facilitate making reusable chunks of actions and responses, simply extend Ardes::ResponsesModule into
|
12
|
+
your action modules. See Ardes::ResponsesModule for details
|
13
|
+
|
14
|
+
* now intercepting template_exists? to decide whether to render a response for an action
|
15
|
+
that has no action method defined. (Removes somewhat mysterious behaviour of empty
|
16
|
+
actions being defined)
|
17
|
+
|
18
|
+
* tagged v0.2.0 - API change, and major internal simplifications - see http://blog.ardes.com/response_for
|
19
|
+
|
20
|
+
* tagged v0.1.0
|
21
|
+
|
22
|
+
* initial release of response_for
|
data/Gemfile
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
response_for_rails (0.4.0)
|
5
|
+
rails (>= 3.0.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
actionmailer (3.2.2)
|
11
|
+
actionpack (= 3.2.2)
|
12
|
+
mail (~> 2.4.0)
|
13
|
+
actionpack (3.2.2)
|
14
|
+
activemodel (= 3.2.2)
|
15
|
+
activesupport (= 3.2.2)
|
16
|
+
builder (~> 3.0.0)
|
17
|
+
erubis (~> 2.7.0)
|
18
|
+
journey (~> 1.0.1)
|
19
|
+
rack (~> 1.4.0)
|
20
|
+
rack-cache (~> 1.1)
|
21
|
+
rack-test (~> 0.6.1)
|
22
|
+
sprockets (~> 2.1.2)
|
23
|
+
activemodel (3.2.2)
|
24
|
+
activesupport (= 3.2.2)
|
25
|
+
builder (~> 3.0.0)
|
26
|
+
activerecord (3.2.2)
|
27
|
+
activemodel (= 3.2.2)
|
28
|
+
activesupport (= 3.2.2)
|
29
|
+
arel (~> 3.0.2)
|
30
|
+
tzinfo (~> 0.3.29)
|
31
|
+
activeresource (3.2.2)
|
32
|
+
activemodel (= 3.2.2)
|
33
|
+
activesupport (= 3.2.2)
|
34
|
+
activesupport (3.2.2)
|
35
|
+
i18n (~> 0.6)
|
36
|
+
multi_json (~> 1.0)
|
37
|
+
arel (3.0.2)
|
38
|
+
builder (3.0.0)
|
39
|
+
diff-lcs (1.1.3)
|
40
|
+
erubis (2.7.0)
|
41
|
+
hike (1.2.1)
|
42
|
+
i18n (0.6.0)
|
43
|
+
journey (1.0.3)
|
44
|
+
json (1.6.5)
|
45
|
+
mail (2.4.4)
|
46
|
+
i18n (>= 0.4.0)
|
47
|
+
mime-types (~> 1.16)
|
48
|
+
treetop (~> 1.4.8)
|
49
|
+
mime-types (1.17.2)
|
50
|
+
multi_json (1.1.0)
|
51
|
+
polyglot (0.3.3)
|
52
|
+
rack (1.4.1)
|
53
|
+
rack-cache (1.2)
|
54
|
+
rack (>= 0.4)
|
55
|
+
rack-ssl (1.3.2)
|
56
|
+
rack
|
57
|
+
rack-test (0.6.1)
|
58
|
+
rack (>= 1.0)
|
59
|
+
rails (3.2.2)
|
60
|
+
actionmailer (= 3.2.2)
|
61
|
+
actionpack (= 3.2.2)
|
62
|
+
activerecord (= 3.2.2)
|
63
|
+
activeresource (= 3.2.2)
|
64
|
+
activesupport (= 3.2.2)
|
65
|
+
bundler (~> 1.0)
|
66
|
+
railties (= 3.2.2)
|
67
|
+
railties (3.2.2)
|
68
|
+
actionpack (= 3.2.2)
|
69
|
+
activesupport (= 3.2.2)
|
70
|
+
rack-ssl (~> 1.3.2)
|
71
|
+
rake (>= 0.8.7)
|
72
|
+
rdoc (~> 3.4)
|
73
|
+
thor (~> 0.14.6)
|
74
|
+
rake (0.9.2.2)
|
75
|
+
rdoc (3.12)
|
76
|
+
json (~> 1.4)
|
77
|
+
rspec (2.8.0)
|
78
|
+
rspec-core (~> 2.8.0)
|
79
|
+
rspec-expectations (~> 2.8.0)
|
80
|
+
rspec-mocks (~> 2.8.0)
|
81
|
+
rspec-core (2.8.0)
|
82
|
+
rspec-expectations (2.8.0)
|
83
|
+
diff-lcs (~> 1.1.2)
|
84
|
+
rspec-mocks (2.8.0)
|
85
|
+
rspec-rails (2.8.1)
|
86
|
+
actionpack (>= 3.0)
|
87
|
+
activesupport (>= 3.0)
|
88
|
+
railties (>= 3.0)
|
89
|
+
rspec (~> 2.8.0)
|
90
|
+
sprockets (2.1.2)
|
91
|
+
hike (~> 1.2)
|
92
|
+
rack (~> 1.0)
|
93
|
+
tilt (~> 1.1, != 1.3.0)
|
94
|
+
sqlite3 (1.3.5)
|
95
|
+
thor (0.14.6)
|
96
|
+
tilt (1.3.3)
|
97
|
+
treetop (1.4.10)
|
98
|
+
polyglot
|
99
|
+
polyglot (>= 0.3.1)
|
100
|
+
tzinfo (0.3.32)
|
101
|
+
|
102
|
+
PLATFORMS
|
103
|
+
ruby
|
104
|
+
|
105
|
+
DEPENDENCIES
|
106
|
+
response_for_rails!
|
107
|
+
rspec (>= 2.5.0)
|
108
|
+
rspec-rails (>= 2.5.0)
|
109
|
+
sqlite3
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2007-2012 Ian White - ian.w.white@ardes.com
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
= response_for
|
2
|
+
|
3
|
+
The gem is called *response_for_rails*
|
4
|
+
|
5
|
+
response_for (see ResponseFor::ActionController::ClassMethods) allows you to decorate the respond_to block of actions on subclassed controllers. This works nicely with http://github.com/ianwhite/resources_controller
|
6
|
+
|
7
|
+
response_for's functionality can be summed up in one sentence:
|
8
|
+
|
9
|
+
<b>"response_for allows you to specify default responses for any action (or before filter) that doesn't render or redirect"</b>
|
10
|
+
|
11
|
+
Actions typically do two things - interact with models, and render a response. The above simple idea allows you to decouple these
|
12
|
+
two functions (where appropriate), which means abstraction of common patterns becomes possible.
|
13
|
+
|
14
|
+
== For Rails 3.0 and higher
|
15
|
+
|
16
|
+
Simply add the response_for_rails gem to your Gemfile
|
17
|
+
|
18
|
+
gem "response_for_rails"
|
19
|
+
|
20
|
+
== Older rails
|
21
|
+
|
22
|
+
=== For Rails 2.2 thru 2.3
|
23
|
+
|
24
|
+
For these older versions of rails please checkout the 0.2-stable-rails2.1 branch. Plugin install on rails 2.2 and up can fetch from a branch.
|
25
|
+
|
26
|
+
./script/plugin install git://github.com/ianwhite/response_for.git -r 0.2-stable-rails2.1
|
27
|
+
|
28
|
+
=== For Rails 2.1
|
29
|
+
|
30
|
+
cd vendor/plugins
|
31
|
+
git clone git://github.com/ianwhite/response_for.git
|
32
|
+
cd response_for
|
33
|
+
git checkout 0.2-stable-rails2.1
|
34
|
+
rmdir -f .git
|
35
|
+
|
36
|
+
=== For Rails 2.0
|
37
|
+
|
38
|
+
Please checkout the 0.1-stable-rails2.0 branch. Same general instructions for Rails 2.1 should work.
|
39
|
+
|
40
|
+
== Run the specs
|
41
|
+
|
42
|
+
To get set up for development, do the following:
|
43
|
+
|
44
|
+
git clone git://github.com/ianwhite/response_for
|
45
|
+
cd response_for
|
46
|
+
cp Gemfile.lock.development Gemfile.lock
|
47
|
+
bundle
|
48
|
+
rake
|
49
|
+
|
50
|
+
== Example
|
51
|
+
|
52
|
+
class FooController < ApplicationController
|
53
|
+
def index
|
54
|
+
@foos = Foo.find(:all)
|
55
|
+
# default response - render html
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# this controller needs to respond_to fbml on index.
|
60
|
+
# Using response_for, we don't need to repeat '@foos = Foo.find(1)'
|
61
|
+
class SpecialFooController < FooController
|
62
|
+
response_for :index do |format|
|
63
|
+
format.fbml { render :inline => turn_into_facebook(@foos) }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
== History
|
68
|
+
|
69
|
+
NOTE: 0.2-stable has BC-breaking API changes, and is supported only for Rails >= 2.1.x. Version 0.2.0 was released on Sept 14th 2008.
|
70
|
+
You should use 0.1-stable in your existing projects until you have runs your specs and whatnot.
|
71
|
+
|
72
|
+
If you want to know more about why I changed the API in 0.2 read on
|
73
|
+
|
74
|
+
|
75
|
+
=== Why change the API in 0.2?
|
76
|
+
|
77
|
+
repsonse_for <= v0.1 intercepted respond_to calls to allow overriding of these by class level declarations. This turns out to have some
|
78
|
+
headaches, such as:
|
79
|
+
|
80
|
+
* If you have some bail-out code in before_filters which uses respond_to, then response_for tries to overwrite this. This meant that I had
|
81
|
+
to write response_for to only kick in once before_filters had run. This made for some funky smelling code.
|
82
|
+
* Sometimes your bail out code runs after the before_filters, in a superclass action for example, or just as part of your action (perhaps in
|
83
|
+
another method). The above hack doesn't work for this case (the before_filters have run). The solution in this case was to use
|
84
|
+
respond_to_without_response_for in any bail out code.
|
85
|
+
* Conceptually, overriding code declared in methods, with code declared at the class level, is weird. Here's an example
|
86
|
+
|
87
|
+
class FooController < SuperclassController
|
88
|
+
response_for :index # override Superclass's index respond_to
|
89
|
+
|
90
|
+
def index
|
91
|
+
respond_to # one might expect this to override the above, as its declared later - but it wont!
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
So, in 0.2 a much simpler idea is behind response_for - you can declare a default response for an action which will be performed
|
96
|
+
if <b>that that action has not already performed a render or redirect</b>. This means that all of your bail out code written with
|
97
|
+
respond_to will do what it's supposed to.
|
98
|
+
|
99
|
+
==== Rewriting for 0.2
|
100
|
+
|
101
|
+
If you're upgrading, you just need to convert any actions you want to override from this:
|
102
|
+
|
103
|
+
def index
|
104
|
+
@things = Thing.all
|
105
|
+
respond_to do |format|
|
106
|
+
format.html
|
107
|
+
format.xml { render :xml => @things }
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
to this:
|
112
|
+
|
113
|
+
def index
|
114
|
+
@things = Thing.all
|
115
|
+
end
|
116
|
+
|
117
|
+
response_for :index |format|
|
118
|
+
format.html
|
119
|
+
format.xml { render :xml => @things }
|
120
|
+
end
|
121
|
+
|
122
|
+
== Previous Versions: 0.1
|
123
|
+
|
124
|
+
There is a branch for rails 2.0 users on this release. If you are using rails 2.0, then you want the 0.1-stable-rails2.0 branch. If you are
|
125
|
+
using rails >= 2.1 then use the 0.1-stable branch
|
126
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'ResponseFor'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
Bundler::GemHelper.install_tasks
|
24
|
+
|
25
|
+
require 'rspec/core/rake_task'
|
26
|
+
|
27
|
+
task :default => [:spec]
|
28
|
+
|
29
|
+
desc "Run the specs"
|
30
|
+
RSpec::Core::RakeTask.new(:spec => []) do |t|
|
31
|
+
t.pattern = "./spec/**/*_spec.rb"
|
32
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
module ResponseFor #:nodoc:
|
2
|
+
# included into ActionController::Base
|
3
|
+
module ActionController
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
extend ClassMethods
|
7
|
+
alias_method_chain :default_render, :response_for
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
# response_for allows you to specify a default response for your actions that don't specify a
|
13
|
+
# respond_to block.
|
14
|
+
#
|
15
|
+
# Using response_for, you may keep the response logic out of the action, so that it can be overriden easily
|
16
|
+
# without having to rewrite the entire action. This is very useful when subclassing controllers.
|
17
|
+
#
|
18
|
+
# == Usage
|
19
|
+
#
|
20
|
+
# response_for :action1 [, :action2], [,:types => [:mime, :type, :list]] [ do |format| ... end] # or
|
21
|
+
#
|
22
|
+
# === Example
|
23
|
+
#
|
24
|
+
# class FooController < ApplicationController
|
25
|
+
# def index
|
26
|
+
# @foos = Foo.find(:all)
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# def show
|
30
|
+
# @foo = Foo.find(params[:id])
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# # this controller needs to respond_to fbml on index, and
|
35
|
+
# # js, html and xml (templates) on index and show
|
36
|
+
# class SpecialFooController < FooController
|
37
|
+
# response_for :index do |format|
|
38
|
+
# format.fbml { render :inline => turn_into_facebook(@foos) }
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# response_for :index, :show, :types => [:html, :xml, :js]
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# === when response_for kicks in
|
45
|
+
#
|
46
|
+
# response_for only kicks in if the action (or any filters) have not already redirected or rendered.
|
47
|
+
#
|
48
|
+
# This means that if you foresee wanting to override your action's responses, you should write them without
|
49
|
+
# a respond_to block, but with a response_for block (the latter can be overridden by subsequent response_fors, the
|
50
|
+
# former cannot)
|
51
|
+
#
|
52
|
+
# === Other examples
|
53
|
+
#
|
54
|
+
# response_for :index, :types => [:fbml] # index will respond to fbml and try to render, say, index.fbml.builder
|
55
|
+
#
|
56
|
+
# response_for :update do |format| # this example is for a resources_controller controller
|
57
|
+
# if !(resource.new_record? || resource.changed?) # => resource.saved?
|
58
|
+
# format.js { render(:update) {|page| page.replace dom_id(resource), :partial => resource }}
|
59
|
+
# else
|
60
|
+
# format.js { render(:update) {|page| page.visual_effect :shake, dom_id(resource) }}
|
61
|
+
# end
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# === Notes
|
65
|
+
#
|
66
|
+
# * If the before_filters or action renders or redirects, then response_for will not be invoked.
|
67
|
+
# * you can stack up multiple response_for calls, the most recent has precedence
|
68
|
+
# * the specifed block is executed within the controller instance, so you can use controller
|
69
|
+
# instance methods and instance variables (i.e. you can make it look just like a regular
|
70
|
+
# respond_to block).
|
71
|
+
# * you can add a response_for an action that has no action method defined. This is just like
|
72
|
+
# defining a template for an action that has no action method defined.
|
73
|
+
# * you can combine the :types option with a block, the block has precedence if you specify the
|
74
|
+
# same mime type in both.
|
75
|
+
def response_for(*actions, &block)
|
76
|
+
(options = actions.extract_options!).assert_valid_keys(:types)
|
77
|
+
|
78
|
+
types_block = if options[:types]
|
79
|
+
proc {|responder| Array(options[:types]).each {|type| responder.send type}}
|
80
|
+
end
|
81
|
+
|
82
|
+
# store responses against action names
|
83
|
+
actions.collect(&:to_s).each do |action|
|
84
|
+
action_responses[action] ||= []
|
85
|
+
action_responses[action].unshift types_block if types_block
|
86
|
+
action_responses[action].unshift block if block
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# remove any response for the specified actions. If no arguments are given,
|
91
|
+
# then all repsonses for all actions are removed
|
92
|
+
def remove_response_for(*actions)
|
93
|
+
if actions.empty?
|
94
|
+
instance_variable_set('@action_responses', nil)
|
95
|
+
else
|
96
|
+
actions.each {|action| action_responses.delete(action.to_s)}
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# return action_responses Hash. On initialize, set and return hash whose values are copies of superclass action_responses, if any
|
101
|
+
def action_responses
|
102
|
+
instance_variable_get('@action_responses') || instance_variable_set('@action_responses', copy_of_each_of_superclass_action_responses)
|
103
|
+
end
|
104
|
+
|
105
|
+
# takes any responses from the argument (a controller, or responses module) and adds them to this controller's responses
|
106
|
+
def include_responses_from(responses_container)
|
107
|
+
responses_container.action_responses.each do |action, responses|
|
108
|
+
action_responses[action] ||= []
|
109
|
+
action_responses[action].unshift(*responses)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
def copy_of_each_of_superclass_action_responses
|
115
|
+
(superclass.action_responses rescue {}).inject({}){|m,(k,v)| m.merge(k => v.dup)}
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
protected
|
120
|
+
# return the responses defined by response_for for the current action
|
121
|
+
def action_responses
|
122
|
+
self.class.action_responses[action_name] || []
|
123
|
+
end
|
124
|
+
|
125
|
+
# respond_to sets the content type on the response, so we use that to tell
|
126
|
+
# if respond_to has been performed
|
127
|
+
def respond_to_performed?
|
128
|
+
(response && response.content_type) ? true : false
|
129
|
+
end
|
130
|
+
|
131
|
+
# if the response.content_type has not been set (if it has, then responthere are responses for the current action, then respond_to them
|
132
|
+
#
|
133
|
+
# we rescue the case where there were no responses, so that the default_render
|
134
|
+
# action will be performed
|
135
|
+
def respond_to_action_responses
|
136
|
+
if !respond_to_performed? && action_responses.any?
|
137
|
+
respond_to do |responder|
|
138
|
+
action_responses.each {|response| instance_exec(responder, &response) }
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# this method is invoked if we've got to the end of an action without
|
144
|
+
# performing, which is when we respond_to any repsonses defined
|
145
|
+
def default_render_with_response_for(*args)
|
146
|
+
respond_to_action_responses
|
147
|
+
default_render_without_response_for(*args) unless performed?
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module ResponseFor#:nodoc:
|
2
|
+
# Extension to facilitate writing responses in mixins
|
3
|
+
#
|
4
|
+
# extend this into your own module to have it act as a response_for namespace
|
5
|
+
# when this module is included into a controller, the responses will be copied
|
6
|
+
# over, along with the actions.
|
7
|
+
#
|
8
|
+
# NOTE: If you are defining self.included on your module, make sure you put the
|
9
|
+
# extend ResponseFor::ResponsesModule *after* self.included method definition.
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
#
|
13
|
+
# module MyActions
|
14
|
+
# extend ResponseFor::ResponsesModule
|
15
|
+
#
|
16
|
+
# def foo
|
17
|
+
# do_foo
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# response_for :foo do |format|
|
21
|
+
# format.html { # do a response }
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# class AController < ApplicationController
|
26
|
+
# include MyActions
|
27
|
+
# # now this controller has foo and response_for :foo
|
28
|
+
# end
|
29
|
+
module ResponsesModule
|
30
|
+
include ResponseFor::ActionController::ClassMethods
|
31
|
+
|
32
|
+
def self.extended(mixin)
|
33
|
+
class << mixin
|
34
|
+
def included_with_responses(controller_class)
|
35
|
+
controller_class.include_responses_from(self)
|
36
|
+
included_without_responses(controller_class)
|
37
|
+
end
|
38
|
+
alias_method_chain :included, :responses
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# BC
|
45
|
+
module Ardes
|
46
|
+
ResponsesModule = ResponseFor::ResponsesModule
|
47
|
+
end
|
data/lib/response_for.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
4
|
+
require 'response_for/version'
|
5
|
+
version = ResponseFor::VERSION
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "response_for_rails"
|
9
|
+
s.version = version
|
10
|
+
s.platform = Gem::Platform::RUBY
|
11
|
+
s.authors = ["Ian White"]
|
12
|
+
s.email = "ian.w.white@gmail.com"
|
13
|
+
s.homepage = "http://github.com/ianwhite/response_for"
|
14
|
+
s.summary = "response_for-#{version}"
|
15
|
+
s.description = "response_for allows you to decorate the respond_to block of actions on subclassed controllers."
|
16
|
+
|
17
|
+
s.rubygems_version = "1.3.7"
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
s.test_files = `git ls-files -- {spec}/*`.split("\n")
|
21
|
+
s.extra_rdoc_files = [ "README.rdoc" ]
|
22
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
23
|
+
s.require_path = "lib"
|
24
|
+
|
25
|
+
s.add_runtime_dependency "rails", '>= 3.0.0'
|
26
|
+
s.add_development_dependency "rspec", '>= 2.5.0'
|
27
|
+
s.add_development_dependency "rspec-rails", '>= 2.5.0'
|
28
|
+
s.add_development_dependency 'sqlite3'
|
29
|
+
s.add_development_dependency "rspec-rails", '>= 2.5.0'
|
30
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<% raise "Boom!" %>
|
File without changes
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
body of an_action.atom
|
@@ -0,0 +1 @@
|
|
1
|
+
body of an_action.html
|
@@ -0,0 +1 @@
|
|
1
|
+
body of an_action.js
|
@@ -0,0 +1 @@
|
|
1
|
+
body of an_action.xml
|
@@ -0,0 +1 @@
|
|
1
|
+
xml.description "body of index.atom.builder"
|
@@ -0,0 +1 @@
|
|
1
|
+
body of index.html.erb
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module DefaultRailsBehaviourSpec
|
4
|
+
class TestController < ApplicationController
|
5
|
+
def two_respond_tos
|
6
|
+
respond_to {|f| f.html { first }}
|
7
|
+
respond_to {|f| f.html { second }}
|
8
|
+
render :text => ""
|
9
|
+
end
|
10
|
+
|
11
|
+
def two_responses
|
12
|
+
respond_to do |f|
|
13
|
+
f.html { first }
|
14
|
+
f.html { second }
|
15
|
+
end
|
16
|
+
render :text => ""
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe TestController do
|
21
|
+
#before(:all) do
|
22
|
+
# Rails.application.routes.draw do
|
23
|
+
# namespace :default_rails_behaviour_spec do
|
24
|
+
# match 'test/:action' => 'test'
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
#end
|
28
|
+
#after(:all) { Rails.application.routes.clear! }
|
29
|
+
|
30
|
+
describe "GET :two_respond_tos" do
|
31
|
+
after { get :two_respond_tos }
|
32
|
+
|
33
|
+
it "should recieve first and second in order" do
|
34
|
+
@controller.should_receive(:first).once.ordered
|
35
|
+
@controller.should_receive(:second).once.ordered
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "GET :two_responses" do
|
40
|
+
after { get :two_responses }
|
41
|
+
|
42
|
+
it "should only receive first and NOT second" do
|
43
|
+
@controller.should_receive(:first).once
|
44
|
+
@controller.should_not_receive(:second)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|