make_resourceful 1.0
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/Rakefile +31 -0
- data/Readme.rdoc +229 -0
- data/VERSION +1 -0
- data/lib/make_resourceful.rb +11 -0
- data/lib/resourceful/base.rb +63 -0
- data/lib/resourceful/builder.rb +405 -0
- data/lib/resourceful/default/accessors.rb +418 -0
- data/lib/resourceful/default/actions.rb +101 -0
- data/lib/resourceful/default/callbacks.rb +51 -0
- data/lib/resourceful/default/responses.rb +118 -0
- data/lib/resourceful/default/urls.rb +136 -0
- data/lib/resourceful/generators/resourceful_scaffold/resourceful_scaffold_generator.rb +87 -0
- data/lib/resourceful/generators/resourceful_scaffold/templates/controller.rb +5 -0
- data/lib/resourceful/generators/resourceful_scaffold/templates/fixtures.yml +10 -0
- data/lib/resourceful/generators/resourceful_scaffold/templates/functional_test.rb +50 -0
- data/lib/resourceful/generators/resourceful_scaffold/templates/helper.rb +2 -0
- data/lib/resourceful/generators/resourceful_scaffold/templates/migration.rb +13 -0
- data/lib/resourceful/generators/resourceful_scaffold/templates/model.rb +2 -0
- data/lib/resourceful/generators/resourceful_scaffold/templates/unit_test.rb +7 -0
- data/lib/resourceful/generators/resourceful_scaffold/templates/view__form.haml +5 -0
- data/lib/resourceful/generators/resourceful_scaffold/templates/view_edit.haml +11 -0
- data/lib/resourceful/generators/resourceful_scaffold/templates/view_index.haml +5 -0
- data/lib/resourceful/generators/resourceful_scaffold/templates/view_new.haml +9 -0
- data/lib/resourceful/generators/resourceful_scaffold/templates/view_partial.haml +12 -0
- data/lib/resourceful/generators/resourceful_scaffold/templates/view_show.haml +14 -0
- data/lib/resourceful/maker.rb +92 -0
- data/lib/resourceful/response.rb +33 -0
- data/lib/resourceful/serialize.rb +185 -0
- data/spec/accessors_spec.rb +474 -0
- data/spec/actions_spec.rb +310 -0
- data/spec/base_spec.rb +12 -0
- data/spec/builder_spec.rb +332 -0
- data/spec/callbacks_spec.rb +71 -0
- data/spec/integration_spec.rb +394 -0
- data/spec/maker_spec.rb +91 -0
- data/spec/response_spec.rb +37 -0
- data/spec/responses_spec.rb +314 -0
- data/spec/serialize_spec.rb +133 -0
- data/spec/urls_spec.rb +282 -0
- metadata +97 -0
@@ -0,0 +1,136 @@
|
|
1
|
+
module Resourceful
|
2
|
+
module Default
|
3
|
+
# This file contains various methods to make URL helpers less painful.
|
4
|
+
# They provide methods analogous to the standard foo_url and foo_path helpers.
|
5
|
+
# However, they use make_resourceful's knowledge of the structure of the controller
|
6
|
+
# to allow you to avoid figuring out which method to call and which parent objects it should be passed.
|
7
|
+
module URLs
|
8
|
+
# This returns the path for the given object,
|
9
|
+
# by default current_object[link:classes/Resourceful/Default/Accessors.html#M000012].
|
10
|
+
# For example, in HatsController the following are equivalent:
|
11
|
+
#
|
12
|
+
# object_path #=> "/hats/12"
|
13
|
+
# hat_path(@hat) #=> "/hats/12"
|
14
|
+
#
|
15
|
+
def object_path(object = current_object); object_route(object, 'path'); end
|
16
|
+
# Same as object_path, but with the protocol and hostname.
|
17
|
+
def object_url (object = current_object); object_route(object, 'url'); end
|
18
|
+
|
19
|
+
# This is the same as object_path,
|
20
|
+
# unless a parent exists.
|
21
|
+
# Then it returns the nested path for the object.
|
22
|
+
# For example, in HatsController where Person has_many :hats and <tt>params[:person_id] == 42</tt>,
|
23
|
+
# the following are equivalent:
|
24
|
+
#
|
25
|
+
# nested_object_path #=> "/person/42/hats/12"
|
26
|
+
# person_hat_path(@person, @hat) #=> "/person/42/hats/12"
|
27
|
+
#
|
28
|
+
def nested_object_path(object = current_object); nested_object_route(object, 'path'); end
|
29
|
+
# Same as nested_object_path, but with the protocol and hostname.
|
30
|
+
def nested_object_url (object = current_object); nested_object_route(object, 'url'); end
|
31
|
+
|
32
|
+
# This returns the path for the edit action for the given object,
|
33
|
+
# by default current_object[link:classes/Resourceful/Default/Accessors.html#M000012].
|
34
|
+
# For example, in HatsController the following are equivalent:
|
35
|
+
#
|
36
|
+
# edit_object_path #=> "/hats/12/edit"
|
37
|
+
# edit_person_hat_path(@person, @hat) #=> "/hats/12/edit"
|
38
|
+
#
|
39
|
+
def edit_object_path(object = current_object); edit_object_route(object, 'path'); end
|
40
|
+
# Same as edit_object_path, but with the protocol and hostname.
|
41
|
+
def edit_object_url (object = current_object); edit_object_route(object, 'url'); end
|
42
|
+
|
43
|
+
# This returns the path for the collection of the current controller.
|
44
|
+
# For example, in HatsController where Person has_many :hats and <tt>params[:person_id] == 42</tt>,
|
45
|
+
# the following are equivalent:
|
46
|
+
#
|
47
|
+
# objects_path #=> "/people/42/hats"
|
48
|
+
# person_hats_path(@person) #=> "/people/42/hats"
|
49
|
+
#
|
50
|
+
def objects_path; objects_route('path'); end
|
51
|
+
# Same as objects_path, but with the protocol and hostname.
|
52
|
+
def objects_url ; objects_route('url'); end
|
53
|
+
|
54
|
+
# This returns the path for the new action for the current controller.
|
55
|
+
# For example, in HatsController where Person has_many :hats and <tt>params[:person_id] == 42</tt>,
|
56
|
+
# the following are equivalent:
|
57
|
+
#
|
58
|
+
# new_object_path #=> "/people/42/hats/new"
|
59
|
+
# new_person_hat_path(@person) #=> "/people/42/hats/new"
|
60
|
+
#
|
61
|
+
def new_object_path; new_object_route('path'); end
|
62
|
+
# Same as new_object_path, but with the protocol and hostname.
|
63
|
+
def new_object_url ; new_object_route('url'); end
|
64
|
+
|
65
|
+
# This returns the path for the parent object.
|
66
|
+
#
|
67
|
+
def parent_path(object = parent_object)
|
68
|
+
instance_route(parent_class_name.underscore, object, 'path')
|
69
|
+
end
|
70
|
+
# Same as parent_path, but with the protocol and hostname.
|
71
|
+
def parent_url(object = parent_object)
|
72
|
+
instance_route(parent_class_name.underscore, object, 'url')
|
73
|
+
end
|
74
|
+
|
75
|
+
# This prefix is added to the Rails URL helper names
|
76
|
+
# before they're called.
|
77
|
+
# By default, it's the underscored list of namespaces of the current controller,
|
78
|
+
# or nil if there are no namespaces defined.
|
79
|
+
# However, it can be overridden if another prefix is needed.
|
80
|
+
# Note that if this is overridden,
|
81
|
+
# the new method should return a string ending in an underscore.
|
82
|
+
#
|
83
|
+
# For example, in Admin::Content::PagesController:
|
84
|
+
#
|
85
|
+
# url_helper_prefix #=> "admin_content_"
|
86
|
+
#
|
87
|
+
# Then object_path is the same as <tt>admin_content_page_path(current_object)</tt>.
|
88
|
+
def url_helper_prefix
|
89
|
+
namespaces.empty? ? nil : "#{namespaces.join('_')}_"
|
90
|
+
end
|
91
|
+
|
92
|
+
# This prefix is added to the Rails URL helper names
|
93
|
+
# for the make_resourceful collection URL helpers,
|
94
|
+
# objects_path and new_object_path.
|
95
|
+
# By default, it's the parent name followed by an underscore if a parent
|
96
|
+
# is given, and the empty string otherwise.
|
97
|
+
#
|
98
|
+
# See also url_helper_prefix.
|
99
|
+
def collection_url_prefix
|
100
|
+
parent? ? "#{parent_class_name.underscore}_" : ''
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def object_route(object, type)
|
106
|
+
instance_route(current_model_name.underscore, object, type)
|
107
|
+
end
|
108
|
+
|
109
|
+
def nested_object_route(object, type)
|
110
|
+
return object_route(object, type) unless parent?
|
111
|
+
send("#{url_helper_prefix}#{parent_class_name.underscore}_#{current_model_name.underscore}_#{type}", parent_object, object)
|
112
|
+
end
|
113
|
+
|
114
|
+
def edit_object_route(object, type)
|
115
|
+
instance_route(current_model_name.underscore, object, type, "edit")
|
116
|
+
end
|
117
|
+
|
118
|
+
def objects_route(type)
|
119
|
+
collection_route(current_model_name.pluralize.underscore, type)
|
120
|
+
end
|
121
|
+
|
122
|
+
def new_object_route(type)
|
123
|
+
collection_route(current_model_name.underscore, type, "new")
|
124
|
+
end
|
125
|
+
|
126
|
+
def instance_route(name, object, type, action = nil)
|
127
|
+
send("#{action ? action + '_' : ''}#{url_helper_prefix}#{collection_url_prefix unless shallow?}#{name}_#{type}", *(parent? && !shallow? ? [parent_object, object] : [object]))
|
128
|
+
end
|
129
|
+
|
130
|
+
def collection_route(name, type, action = nil)
|
131
|
+
send("#{action ? action + '_' : ''}#{url_helper_prefix}#{collection_url_prefix}#{name}_#{type}",
|
132
|
+
*(parent? ? [parent_object] : []))
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
class ResourcefulScaffoldGenerator < Rails::Generators::Base
|
2
|
+
attr_reader :controller_class_path,
|
3
|
+
:controller_file_path,
|
4
|
+
:controller_class_nesting,
|
5
|
+
:controller_class_nesting_depth,
|
6
|
+
:controller_class_name,
|
7
|
+
:controller_underscore_name,
|
8
|
+
:controller_plural_name
|
9
|
+
alias_method :controller_file_name, :controller_underscore_name
|
10
|
+
alias_method :controller_table_name, :controller_plural_name
|
11
|
+
|
12
|
+
def initialize(runtime_args, runtime_options = {})
|
13
|
+
super
|
14
|
+
|
15
|
+
base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@name.pluralize)
|
16
|
+
@controller_class_name_without_nesting, @controller_underscore_name, @controller_plural_name = inflect_names(base_name)
|
17
|
+
|
18
|
+
if @controller_class_nesting.empty?
|
19
|
+
@controller_class_name = @controller_class_name_without_nesting
|
20
|
+
else
|
21
|
+
@controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def manifest
|
26
|
+
record do |m|
|
27
|
+
# Check for class naming collisions.
|
28
|
+
m.class_collisions(controller_class_path, "#{controller_class_name}Controller", "#{controller_class_name}Helper")
|
29
|
+
m.class_collisions(class_path, "#{class_name}")
|
30
|
+
|
31
|
+
# Controller, helper, views, and test directories.
|
32
|
+
m.directory(File.join('app/models', class_path))
|
33
|
+
m.directory(File.join('app/controllers', controller_class_path))
|
34
|
+
m.directory(File.join('app/helpers', controller_class_path))
|
35
|
+
m.directory(File.join('app/views', controller_class_path, controller_file_name))
|
36
|
+
m.directory(File.join('test/functional', controller_class_path))
|
37
|
+
m.directory(File.join('test/unit', class_path))
|
38
|
+
m.directory(File.join('test/fixtures', class_path))
|
39
|
+
|
40
|
+
# Views
|
41
|
+
for action in scaffold_views
|
42
|
+
m.template("view_#{action}.haml", File.join('app/views', controller_class_path, controller_file_name, "#{action}.html.haml"))
|
43
|
+
end
|
44
|
+
m.template('view_partial.haml', File.join('app/views', controller_class_path, controller_file_name, "_#{singular_name}.html.haml"))
|
45
|
+
|
46
|
+
# Helper
|
47
|
+
m.template('helper.rb', File.join('app/helpers', controller_class_path, "#{controller_file_name}_helper.rb"))
|
48
|
+
|
49
|
+
# Model
|
50
|
+
m.template('model.rb', File.join('app/models', class_path, "#{file_name}.rb"))
|
51
|
+
|
52
|
+
unless options[:skip_migration]
|
53
|
+
m.migration_template('migration.rb', 'db/migrate',
|
54
|
+
:assigns => {
|
55
|
+
:migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}",
|
56
|
+
:attributes => attributes
|
57
|
+
},
|
58
|
+
:migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}")
|
59
|
+
end
|
60
|
+
|
61
|
+
# Controller
|
62
|
+
m.template('controller.rb', File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb"))
|
63
|
+
|
64
|
+
# Tests
|
65
|
+
m.template('functional_test.rb', File.join('test/functional', controller_class_path, "#{controller_file_name}_controller_test.rb"))
|
66
|
+
m.template('unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb"))
|
67
|
+
m.template('fixtures.yml', File.join('test/fixtures', "#{table_name}.yml"))
|
68
|
+
|
69
|
+
# Route
|
70
|
+
m.route_resources controller_file_name
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
protected
|
75
|
+
|
76
|
+
def banner
|
77
|
+
"Usage: #{$0} resourcefulscaffold ModelName [field:type, field:type]"
|
78
|
+
end
|
79
|
+
|
80
|
+
def scaffold_views
|
81
|
+
%w[ index show new edit _form ]
|
82
|
+
end
|
83
|
+
|
84
|
+
def model_name
|
85
|
+
class_name.demodulize
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require File.dirname(__FILE__) + '<%= '/..' * controller_class_nesting_depth %>/../test_helper'
|
2
|
+
require '<%= controller_file_path %>_controller'
|
3
|
+
|
4
|
+
# Re-raise errors caught by the controller.
|
5
|
+
class <%= controller_class_name %>Controller; def rescue_action(e) raise e end; end
|
6
|
+
|
7
|
+
class <%= controller_class_name %>ControllerTest < ActionController::TestCase
|
8
|
+
|
9
|
+
def test_should_get_index
|
10
|
+
get :index
|
11
|
+
assert_response :success
|
12
|
+
assert assigns(:<%= table_name %>)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_should_get_new
|
16
|
+
get :new
|
17
|
+
assert_response :success
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_should_create_<%= file_name %>
|
21
|
+
old_count = <%= class_name %>.count
|
22
|
+
post :create, :<%= file_name %> => { }
|
23
|
+
assert_equal old_count + 1, <%= class_name %>.count
|
24
|
+
|
25
|
+
assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_should_show_<%= file_name %>
|
29
|
+
get :show, :id => 1
|
30
|
+
assert_response :success
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_should_get_edit
|
34
|
+
get :edit, :id => 1
|
35
|
+
assert_response :success
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_should_update_<%= file_name %>
|
39
|
+
put :update, :id => 1, :<%= file_name %> => { }
|
40
|
+
assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_should_destroy_<%= file_name %>
|
44
|
+
old_count = <%= class_name %>.count
|
45
|
+
delete :destroy, :id => 1
|
46
|
+
assert_equal old_count-1, <%= class_name %>.count
|
47
|
+
|
48
|
+
assert_redirected_to <%= table_name %>_path
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class <%= migration_name %> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :<%= table_name %>, :force => true do |t|
|
4
|
+
<% for attribute in attributes -%>
|
5
|
+
t.column :<%= attribute.name %>, :<%= attribute.type %>
|
6
|
+
<% end -%>
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.down
|
11
|
+
drop_table :<%= table_name %>
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
%h1 Editing <%= singular_name %>
|
2
|
+
|
3
|
+
= error_messages_for :<%= singular_name %>
|
4
|
+
|
5
|
+
= form_for(:<%= singular_name %>, :url => object_url, :html => { :method => :put }) do |f|
|
6
|
+
= render :partial => "form", :locals => {:f => f}
|
7
|
+
%p= submit_tag "Update"
|
8
|
+
|
9
|
+
= link_to 'Show', object_path
|
10
|
+
|
|
11
|
+
= link_to 'Back', objects_path
|
@@ -0,0 +1,12 @@
|
|
1
|
+
%div[<%= singular_name %>]
|
2
|
+
<% for attribute in attributes -%>
|
3
|
+
%p.<%= attribute.name %>
|
4
|
+
%strong <%= attribute.column.human_name %>
|
5
|
+
= h <%= singular_name %>.<%= attribute.name %>
|
6
|
+
<% end -%>
|
7
|
+
|
8
|
+
= link_to 'Show', object_path(<%= singular_name %>)
|
9
|
+
|
|
10
|
+
= link_to 'Edit', edit_object_path(<%= singular_name %>)
|
11
|
+
|
|
12
|
+
= link_to 'Destroy', object_path(<%= singular_name %>), :confirm => 'Really destroy <%= singular_name %>?', :method => :delete
|
@@ -0,0 +1,14 @@
|
|
1
|
+
%h1 Viewing <%= singular_name %>
|
2
|
+
|
3
|
+
%div[current_object]
|
4
|
+
<% for attribute in attributes -%>
|
5
|
+
%p.<%= attribute.name %>
|
6
|
+
%strong <%= attribute.column.human_name %>
|
7
|
+
= h current_object.<%= attribute.name %>
|
8
|
+
<% end -%>
|
9
|
+
|
10
|
+
= link_to 'Edit', edit_object_path
|
11
|
+
|
|
12
|
+
= link_to 'Destroy', object_path, :confirm => 'Really destroy <%= singular_name %>?', :method => :delete
|
13
|
+
|
|
14
|
+
= link_to 'Back', objects_path
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'resourceful/builder'
|
2
|
+
require 'resourceful/base'
|
3
|
+
|
4
|
+
module Resourceful
|
5
|
+
# This module is extended by the ActionController::Base class object.
|
6
|
+
# It provides the actual +make_resourceful+ method
|
7
|
+
# and sets up the controller so that everything will work.
|
8
|
+
module Maker
|
9
|
+
# Called automatically on ActionController::Base.
|
10
|
+
# Initializes various inheritable attributes.
|
11
|
+
def self.extended(base)
|
12
|
+
base.class_attribute :resourceful_callbacks
|
13
|
+
base.class_attribute :resourceful_responses
|
14
|
+
base.class_attribute :parents
|
15
|
+
base.class_attribute :shallow_parent
|
16
|
+
base.class_attribute :model_namespace
|
17
|
+
base.class_attribute :made_resourceful
|
18
|
+
|
19
|
+
base.resourceful_callbacks = {}
|
20
|
+
base.resourceful_responses = {}
|
21
|
+
base.parents = []
|
22
|
+
base.model_namespace = nil
|
23
|
+
base.made_resourceful = false
|
24
|
+
end
|
25
|
+
|
26
|
+
# :call-seq:
|
27
|
+
# make_resourceful(options = {}) { ... }
|
28
|
+
#
|
29
|
+
# This is the central method, and namesake, of make_resourceful.
|
30
|
+
# It takes a block and evaluates it in the context of a Builder,
|
31
|
+
# allowing the controller to be customized extensively.
|
32
|
+
#
|
33
|
+
# See Resourceful::Builder for documentation on the methods available
|
34
|
+
# in the context of the block.
|
35
|
+
#
|
36
|
+
# The only option currently available is <tt>:include</tt>.
|
37
|
+
# It takes an object that responds to to_proc
|
38
|
+
# (or an array of such objects)
|
39
|
+
# and evaluates that proc in the same context as the block.
|
40
|
+
# For example:
|
41
|
+
#
|
42
|
+
# make_resourceful :include => proc { actions :all } do
|
43
|
+
# before :show do
|
44
|
+
# current_object.current_user = current_user
|
45
|
+
# end
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# This is the same as:
|
49
|
+
#
|
50
|
+
# make_resourceful do
|
51
|
+
# actions :all
|
52
|
+
# before :show do
|
53
|
+
# current_object.current_user = current_user
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
def make_resourceful(options = {}, &block)
|
58
|
+
# :stopdoc:
|
59
|
+
include Resourceful::Base
|
60
|
+
# :startdoc:
|
61
|
+
|
62
|
+
builder = Resourceful::Builder.new(self)
|
63
|
+
unless builder.inherited?
|
64
|
+
Resourceful::Base.made_resourceful.each { |proc| builder.instance_eval(&proc) }
|
65
|
+
end
|
66
|
+
Array(options[:include]).each { |proc| builder.instance_eval(&proc) }
|
67
|
+
builder.instance_eval(&block)
|
68
|
+
|
69
|
+
builder.apply
|
70
|
+
|
71
|
+
add_helpers
|
72
|
+
end
|
73
|
+
|
74
|
+
# Returns whether or not make_resourceful has been called
|
75
|
+
# on this controller or any controllers it inherits from.
|
76
|
+
def made_resourceful?
|
77
|
+
self.class.made_resourceful
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def add_helpers
|
83
|
+
helper_method(:object_path, :objects_path, :new_object_path, :edit_object_path,
|
84
|
+
:object_url, :objects_url, :new_object_url, :edit_object_url,
|
85
|
+
:parent_path, :parent_url,
|
86
|
+
:nested_object_path, :nested_object_url,
|
87
|
+
:current_objects, :current_object, :current_model, :current_model_name,
|
88
|
+
:namespaces, :instance_variable_name, :parent_names, :parent_name,
|
89
|
+
:parent?, :parent_model, :parent_object, :save_succeeded?)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Resourceful
|
2
|
+
# This is the class of the object passed to the Builder#response_for method.
|
3
|
+
# It shouldn't be used by users.
|
4
|
+
#
|
5
|
+
# The Response collects format procs
|
6
|
+
# and returns them with the format method,
|
7
|
+
# in the order they were given.
|
8
|
+
# For example:
|
9
|
+
#
|
10
|
+
# response.html { redirect_to '/' }
|
11
|
+
# response.xml { render :xml => current_object.to_xml }
|
12
|
+
# response.js
|
13
|
+
# response.formats #=> [[:html, #<Proc>], [:xml, #<Proc>], [:js, #<Proc>]]
|
14
|
+
#
|
15
|
+
# Note that the <tt>:js</tt> response is the empty proc -
|
16
|
+
# the same as <tt>proc {}</tt>.
|
17
|
+
class Response # :nodoc:
|
18
|
+
# Returns a list of pairs of formats and procs
|
19
|
+
# representing the formats passed to the response object.
|
20
|
+
# See class description.
|
21
|
+
attr :formats
|
22
|
+
|
23
|
+
# Returns a new Response with no format data.
|
24
|
+
def initialize
|
25
|
+
@formats = []
|
26
|
+
end
|
27
|
+
|
28
|
+
# Used to dispatch the individual format methods.
|
29
|
+
def method_missing(name, &block)
|
30
|
+
@formats.push([name, block || proc {}]) unless @formats.any? {|n,b| n == name}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|