actionpack 2.0.2 → 2.0.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (74) hide show
  1. data/CHANGELOG +45 -0
  2. data/Rakefile +5 -3
  3. data/lib/action_controller.rb +0 -0
  4. data/lib/action_controller/assertions/response_assertions.rb +6 -2
  5. data/lib/action_controller/assertions/routing_assertions.rb +5 -2
  6. data/lib/action_controller/base.rb +4 -3
  7. data/lib/action_controller/cgi_ext/cookie.rb +1 -1
  8. data/lib/action_controller/filters.rb +5 -3
  9. data/lib/action_controller/http_authentication.rb +2 -4
  10. data/lib/action_controller/integration.rb +3 -2
  11. data/lib/action_controller/layout.rb +14 -15
  12. data/lib/action_controller/mime_type.rb +4 -1
  13. data/lib/action_controller/polymorphic_routes.rb +90 -15
  14. data/lib/action_controller/record_identifier.rb +4 -4
  15. data/lib/action_controller/request.rb +29 -14
  16. data/lib/action_controller/request_forgery_protection.rb +41 -34
  17. data/lib/action_controller/request_profiler.rb +16 -6
  18. data/lib/action_controller/response.rb +0 -0
  19. data/lib/action_controller/routing.rb +3 -3
  20. data/lib/action_controller/session/active_record_store.rb +7 -8
  21. data/lib/action_controller/session/cookie_store.rb +2 -3
  22. data/lib/action_controller/templates/rescues/_trace.erb +5 -5
  23. data/lib/action_controller/test_case.rb +24 -4
  24. data/lib/action_controller/test_process.rb +3 -3
  25. data/lib/action_controller/url_rewriter.rb +29 -28
  26. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +2 -2
  27. data/lib/action_controller/verification.rb +73 -57
  28. data/lib/action_pack/version.rb +1 -1
  29. data/lib/action_view/base.rb +24 -6
  30. data/lib/action_view/helpers/active_record_helper.rb +1 -1
  31. data/lib/action_view/helpers/asset_tag_helper.rb +12 -6
  32. data/lib/action_view/helpers/atom_feed_helper.rb +21 -17
  33. data/lib/action_view/helpers/date_helper.rb +6 -6
  34. data/lib/action_view/helpers/form_helper.rb +3 -2
  35. data/lib/action_view/helpers/form_options_helper.rb +12 -1
  36. data/lib/action_view/helpers/form_tag_helper.rb +18 -0
  37. data/lib/action_view/helpers/number_helper.rb +1 -1
  38. data/lib/action_view/helpers/prototype_helper.rb +1 -1
  39. data/lib/action_view/helpers/text_helper.rb +1 -1
  40. data/lib/action_view/helpers/url_helper.rb +5 -9
  41. data/lib/action_view/template_error.rb +11 -4
  42. data/test/activerecord/active_record_store_test.rb +1 -1
  43. data/test/activerecord/fixtures_test.rb +24 -0
  44. data/test/controller/action_pack_assertions_test.rb +37 -2
  45. data/test/controller/base_test.rb +4 -1
  46. data/test/controller/cgi_test.rb +4 -3
  47. data/test/controller/filters_test.rb +4 -7
  48. data/test/controller/html-scanner/sanitizer_test.rb +7 -1
  49. data/test/controller/integration_test.rb +0 -1
  50. data/test/controller/mime_type_test.rb +5 -0
  51. data/test/controller/new_render_test.rb +25 -2
  52. data/test/controller/polymorphic_routes_test.rb +106 -75
  53. data/test/controller/redirect_test.rb +11 -0
  54. data/test/controller/render_test.rb +19 -0
  55. data/test/controller/request_forgery_protection_test.rb +9 -0
  56. data/test/controller/request_test.rb +33 -5
  57. data/test/controller/routing_test.rb +4 -4
  58. data/test/controller/session/cookie_store_test.rb +0 -0
  59. data/test/controller/test_test.rb +43 -1
  60. data/test/controller/url_rewriter_test.rb +34 -4
  61. data/test/fixtures/layouts/block_with_layout.erb +3 -0
  62. data/test/fixtures/layouts/partial_with_layout.erb +3 -0
  63. data/test/template/asset_tag_helper_test.rb +17 -13
  64. data/test/template/atom_feed_helper_test.rb +52 -2
  65. data/test/template/compiled_templates_test.rb +5 -1
  66. data/test/template/date_helper_test.rb +1 -1
  67. data/test/template/deprecate_ivars_test.rb +51 -0
  68. data/test/template/form_options_helper_test.rb +29 -0
  69. data/test/template/form_tag_helper_test.rb +18 -0
  70. data/test/template/number_helper_test.rb +1 -0
  71. data/test/template/text_helper_test.rb +32 -14
  72. data/test/template/url_helper_test.rb +1 -1
  73. data/test/testing_sandbox.rb +8 -4
  74. metadata +9 -4
data/CHANGELOG CHANGED
@@ -1,3 +1,48 @@
1
+ *2.0.4* (2nd September 2008)
2
+
3
+ * Avoid remote_ip spoofing. [Brian Candler]
4
+
5
+ * Correct inconsistencies in RequestForgeryProtection docs. #11032 [mislav]
6
+
7
+ * Make assert_routing aware of the HTTP method used. #8039 [mpalmer]
8
+ e.g. assert_routing({ :method => 'put', :path => '/product/321' }, { :controller => "product", :action => "update", :id => "321" })
9
+
10
+ * Remove ERB trim variables from trace template in case ActionView::Base.erb_trim_mode is changed in the application. #10098 [tpope, kampers]
11
+
12
+ * Fix typo in form_helper documentation. #10650 [xaviershay, kampers]
13
+
14
+ * Fix bug with setting Request#format= after the getter has cached the value. #10889 [cch1]
15
+
16
+ * Add label_tag helper for generating elements. #10802 [DefV]
17
+
18
+ * TestSession supports indifferent access. #7372 [tamc, Arsen7, mhackett, julik, jean.helou]
19
+
20
+ * UrlWriter respects relative_url_root. #10748 [Cheah Chu Yeow]
21
+
22
+ * Support render :text => nil. #6684 [tjennings, PotatoSalad, Cheah Chu Yeow]
23
+
24
+ * assert_response failures include the exception message. #10688 [Seth Rasmussen]
25
+
26
+ * Fixed rendering of partials with layout when done from site layout #9209 [antramm]
27
+
28
+ * Fix atom_feed_helper to comply with the atom spec. Closes #10672 [xaviershay]
29
+
30
+ * The tags created do not contain a date (http://feedvalidator.org/docs/error/InvalidTAG.html)
31
+ * IDs are not guaranteed unique
32
+ * A default self link was not provided, contrary to the documentation
33
+ * NOTE: This changes tags for existing atom entries, but at least they validate now.
34
+
35
+ * Correct indentation in tests. Closes #10671 [l.guidi]
36
+
37
+ * Fix that auto_link looks for ='s in url paths (Amazon urls have them). Closes #10640 [bgreenlee]
38
+
39
+ * Ensure that test case setup is run even if overridden. #10382 [Josh Peek]
40
+
41
+ * Fix HTML Sanitizer to allow trailing spaces in CSS style attributes. Closes #10566 [wesley.moxam]
42
+
43
+ * Add :default option to time_zone_select. #10590 [Matt Aimonetti]
44
+
45
+
1
46
  *2.0.2* (December 16th, 2007)
2
47
 
3
48
  * Added delete_via_redirect and put_via_redirect to integration testing #10497 [philodespotos]
data/Rakefile CHANGED
@@ -4,6 +4,7 @@ require 'rake/testtask'
4
4
  require 'rake/rdoctask'
5
5
  require 'rake/packagetask'
6
6
  require 'rake/gempackagetask'
7
+ require 'rake/contrib/sshpublisher'
7
8
  require 'rake/contrib/rubyforgepublisher'
8
9
  require File.join(File.dirname(__FILE__), 'lib', 'action_pack', 'version')
9
10
 
@@ -76,7 +77,7 @@ spec = Gem::Specification.new do |s|
76
77
  s.has_rdoc = true
77
78
  s.requirements << 'none'
78
79
 
79
- s.add_dependency('activesupport', '= 2.0.2' + PKG_BUILD)
80
+ s.add_dependency('activesupport', '= 2.0.4' + PKG_BUILD)
80
81
 
81
82
  s.require_path = 'lib'
82
83
  s.autorequire = 'action_controller'
@@ -132,8 +133,8 @@ task :update_js => [ :update_scriptaculous ]
132
133
 
133
134
  desc "Publish the API documentation"
134
135
  task :pgem => [:package] do
135
- Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
136
- `ssh davidhh@wrath.rubyonrails.org './gemupdate.sh'`
136
+ Rake::SshFilePublisher.new("david@greed.loudthinking.com", "/u/sites/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
137
+ `ssh david@greed.loudthinking.com '/u/sites/gems/gemupdate.sh'`
137
138
  end
138
139
 
139
140
  desc "Publish the API documentation"
@@ -144,6 +145,7 @@ end
144
145
  desc "Publish the release files to RubyForge."
145
146
  task :release => [ :package ] do
146
147
  require 'rubyforge'
148
+ require 'rake/contrib/rubyforgepublisher'
147
149
 
148
150
  packages = %w( gem tgz zip ).collect{ |ext| "pkg/#{PKG_NAME}-#{PKG_VERSION}.#{ext}" }
149
151
 
File without changes
@@ -33,7 +33,11 @@ module ActionController
33
33
  elsif type.is_a?(Symbol) && @response.response_code == ActionController::StatusCodes::SYMBOL_TO_STATUS_CODE[type]
34
34
  assert_block("") { true } # to count the assertion
35
35
  else
36
- assert_block(build_message(message, "Expected response to be a <?>, but was <?>", type, @response.response_code)) { false }
36
+ if @response.error?
37
+ assert_block(build_message(message, "Expected response to be a <?>, but was <?>\n<?>", type, @response.response_code, @response.template.instance_variable_get(:@exception).message)) { false }
38
+ else
39
+ assert_block(build_message(message, "Expected response to be a <?>, but was <?>", type, @response.response_code)) { false }
40
+ end
37
41
  end
38
42
  end
39
43
  end
@@ -91,7 +95,7 @@ module ActionController
91
95
  value['controller'] = value['controller'].to_s
92
96
  if key == :actual && value['controller'].first != '/' && !value['controller'].include?('/')
93
97
  new_controller_path = ActionController::Routing.controller_relative_to(value['controller'], @controller.class.controller_path)
94
- value['controller'] = new_controller_path if value['controller'] != new_controller_path && ActionController::Routing.possible_controllers.include?(new_controller_path)
98
+ value['controller'] = new_controller_path if value['controller'] != new_controller_path && ActionController::Routing.possible_controllers.include?(new_controller_path) && @response.redirected_to.is_a?(Hash)
95
99
  end
96
100
  value['controller'] = value['controller'][1..-1] if value['controller'].first == '/' # strip leading hash
97
101
  end
@@ -114,6 +114,9 @@ module ActionController
114
114
  #
115
115
  # # Tests a route, providing a defaults hash
116
116
  # assert_routing 'controller/action/9', {:id => "9", :item => "square"}, {:controller => "controller", :action => "action"}, {}, {:item => "square"}
117
+ #
118
+ # # Tests a route with a HTTP method
119
+ # assert_routing({ :method => 'put', :path => '/product/321' }, { :controller => "product", :action => "update", :id => "321" })
117
120
  def assert_routing(path, options, defaults={}, extras={}, message=nil)
118
121
  assert_recognizes(options, path, extras, message)
119
122
 
@@ -122,7 +125,7 @@ module ActionController
122
125
  options[:controller] = "/#{controller}"
123
126
  end
124
127
 
125
- assert_generates(path, options, defaults, extras, message)
128
+ assert_generates(path.is_a?(Hash) ? path[:path] : path, options, defaults, extras, message)
126
129
  end
127
130
 
128
131
  private
@@ -140,4 +143,4 @@ module ActionController
140
143
  end
141
144
  end
142
145
  end
143
- end
146
+ end
@@ -850,8 +850,8 @@ module ActionController #:nodoc:
850
850
  response.headers["Location"] = url_for(location)
851
851
  end
852
852
 
853
- if text = options[:text]
854
- render_for_text(text, options[:status])
853
+ if options.has_key?(:text)
854
+ render_for_text(options[:text], options[:status])
855
855
 
856
856
  else
857
857
  if file = options[:file]
@@ -1029,7 +1029,8 @@ module ActionController #:nodoc:
1029
1029
  # RedirectBackError will be raised. You may specify some fallback
1030
1030
  # behavior for this case by rescuing RedirectBackError.
1031
1031
  def redirect_to(options = {}, response_status = {}) #:doc:
1032
-
1032
+ raise ActionControllerError.new("Cannot redirect to nil!") if options.nil?
1033
+
1033
1034
  if options.is_a?(Hash) && options[:status]
1034
1035
  status = options.delete(:status)
1035
1036
  elsif response_status[:status]
@@ -89,7 +89,7 @@ class CGI #:nodoc:
89
89
  cookies = Hash.new([])
90
90
 
91
91
  if raw_cookie
92
- raw_cookie.split(/[;,]\s?/).each do |pairs|
92
+ raw_cookie.split(/;\s?/).each do |pairs|
93
93
  name, values = pairs.split('=',2)
94
94
  next unless name and values
95
95
  name = CGI::unescape(name)
@@ -583,10 +583,12 @@ module ActionController #:nodoc:
583
583
  when filter.respond_to?(:call)
584
584
  if filter.is_a?(Method)
585
585
  MethodFilter
586
- elsif filter.arity == 1
587
- ProcFilter
588
586
  else
589
- ProcWithCallFilter
587
+ case filter.arity
588
+ when 1; ProcFilter
589
+ when 2; ProcWithCallFilter
590
+ else raise ArgumentError, 'Filter blocks must take one or two arguments.'
591
+ end
590
592
  end
591
593
  when filter.respond_to?(:filter)
592
594
  ClassFilter
@@ -1,5 +1,3 @@
1
- require 'base64'
2
-
3
1
  module ActionController
4
2
  module HttpAuthentication
5
3
  # Makes it dead easy to do HTTP Basic authentication.
@@ -110,11 +108,11 @@ module ActionController
110
108
  end
111
109
 
112
110
  def decode_credentials(request)
113
- Base64.decode64(authorization(request).split.last || '')
111
+ ActiveSupport::Base64.decode64(authorization(request).split.last || '')
114
112
  end
115
113
 
116
114
  def encode_credentials(user_name, password)
117
- "Basic #{Base64.encode64("#{user_name}:#{password}")}"
115
+ "Basic #{ActiveSupport::Base64.encode64("#{user_name}:#{password}")}"
118
116
  end
119
117
 
120
118
  def authentication_request(controller, realm)
@@ -1,6 +1,7 @@
1
- require 'dispatcher'
2
1
  require 'stringio'
3
2
  require 'uri'
3
+
4
+ require 'action_controller/dispatcher'
4
5
  require 'action_controller/test_process'
5
6
 
6
7
  module ActionController
@@ -276,7 +277,7 @@ module ActionController
276
277
  ActionController::Base.clear_last_instantiation!
277
278
 
278
279
  cgi = StubCGI.new(env, data)
279
- Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, cgi.stdoutput)
280
+ ActionController::Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, cgi.stdoutput)
280
281
  @result = cgi.stdoutput.string
281
282
  @request_count += 1
282
283
 
@@ -29,18 +29,20 @@ module ActionController #:nodoc:
29
29
  #
30
30
  # // The header part of this layout
31
31
  # <%= yield %>
32
- # // The footer part of this layout -->
32
+ # // The footer part of this layout
33
33
  #
34
34
  # And then you have content pages that look like this:
35
35
  #
36
36
  # hello world
37
37
  #
38
- # Not a word about common structures. At rendering time, the content page is computed and then inserted in the layout,
39
- # like this:
38
+ # At rendering time, the content page is computed and then inserted in the layout, like this:
40
39
  #
41
40
  # // The header part of this layout
42
41
  # hello world
43
- # // The footer part of this layout -->
42
+ # // The footer part of this layout
43
+ #
44
+ # NOTE: The old notation for rendering the view from a layout was to expose the magic <tt>@content_for_layout</tt> instance
45
+ # variable. The preferred notation now is to use <tt>yield</tt>, as documented above.
44
46
  #
45
47
  # == Accessing shared variables
46
48
  #
@@ -124,7 +126,7 @@ module ActionController #:nodoc:
124
126
  # class WeblogController < ActionController::Base
125
127
  # layout "weblog_standard"
126
128
  #
127
- # If no directory is specified for the template name, the template will by default be looked for in +app/views/layouts/+.
129
+ # If no directory is specified for the template name, the template will by default be looked for in <tt>app/views/layouts/</tt>.
128
130
  # Otherwise, it will be looked up relative to the template root.
129
131
  #
130
132
  # == Conditional layouts
@@ -149,23 +151,20 @@ module ActionController #:nodoc:
149
151
  # == Using a different layout in the action render call
150
152
  #
151
153
  # If most of your actions use the same layout, it makes perfect sense to define a controller-wide layout as described above.
152
- # Some times you'll have exceptions, though, where one action wants to use a different layout than the rest of the controller.
153
- # This is possible using the <tt>render</tt> method. It's just a bit more manual work as you'll have to supply fully
154
- # qualified template and layout names as this example shows:
154
+ # Sometimes you'll have exceptions where one action wants to use a different layout than the rest of the controller.
155
+ # You can do this by passing a <tt>:layout</tt> option to the <tt>render</tt> call. For example:
155
156
  #
156
157
  # class WeblogController < ActionController::Base
158
+ # layout "weblog_standard"
159
+ #
157
160
  # def help
158
- # render :action => "help/index", :layout => "help"
161
+ # render :action => "help", :layout => "help"
159
162
  # end
160
163
  # end
161
164
  #
162
- # As you can see, you pass the template as the first parameter, the status code as the second ("200" is OK), and the layout
163
- # as the third.
164
- #
165
- # NOTE: The old notation for rendering the view from a layout was to expose the magic <tt>@content_for_layout</tt> instance
166
- # variable. The preferred notation now is to use <tt>yield</tt>, as documented above.
165
+ # This will render the help action with the "help" layout instead of the controller-wide "weblog_standard" layout.
167
166
  module ClassMethods
168
- # If a layout is specified, all rendered actions will have their result rendered
167
+ # If a layout is specified, all rendered actions will have their result rendered
169
168
  # when the layout <tt>yield</tt>s. This layout can itself depend on instance variables assigned during action
170
169
  # performance and have access to them as any normal template would.
171
170
  def layout(template_name, conditions = {}, auto = false)
@@ -145,7 +145,10 @@ module Mime
145
145
  end
146
146
 
147
147
  def ==(mime_type)
148
- (@synonyms + [ self ]).any? { |synonym| synonym.to_s == mime_type.to_s } if mime_type
148
+ return false unless mime_type
149
+ (@synonyms + [ self ]).any? do |synonym|
150
+ synonym.to_s == mime_type.to_s || synonym.to_sym == mime_type.to_sym
151
+ end
149
152
  end
150
153
 
151
154
  private
@@ -1,8 +1,75 @@
1
1
  module ActionController
2
+ # Polymorphic URL helpers are methods for smart resolution to a named route call when
3
+ # given an ActiveRecord model instance. They are to be used in combination with
4
+ # ActionController::Resources.
5
+ #
6
+ # These methods are useful when you want to generate correct URL or path to a RESTful
7
+ # resource without having to know the exact type of the record in question.
8
+ #
9
+ # Nested resources and/or namespaces are also supported, as illustrated in the example:
10
+ #
11
+ # polymorphic_url([:admin, @article, @comment])
12
+ # #-> results in:
13
+ # admin_article_comment_url(@article, @comment)
14
+ #
15
+ # == Usage within the framework
16
+ #
17
+ # Polymorphic URL helpers are used in a number of places throughout the Rails framework:
18
+ #
19
+ # * <tt>url_for</tt>, so you can use it with a record as the argument, e.g.
20
+ # <tt>url_for(@article)</tt>;
21
+ # * ActionView::Helpers::FormHelper uses <tt>polymorphic_path</tt>, so you can write
22
+ # <tt>form_for(@article)</tt> without having to specify :url parameter for the form
23
+ # action;
24
+ # * <tt>redirect_to</tt> (which, in fact, uses <tt>url_for</tt>) so you can write
25
+ # <tt>redirect_to(post)</tt> in your controllers;
26
+ # * ActionView::Helpers::AtomFeedHelper, so you don't have to explicitly specify URLs
27
+ # for feed entries.
28
+ #
29
+ # == Prefixed polymorphic helpers
30
+ #
31
+ # In addition to <tt>polymorphic_url</tt> and <tt>polymorphic_path</tt> methods, a
32
+ # number of prefixed helpers are available as a shorthand to <tt>:action => "..."</tt>
33
+ # in options. Those are:
34
+ #
35
+ # * <tt>edit_polymorphic_url</tt>, <tt>edit_polymorphic_path</tt>
36
+ # * <tt>new_polymorphic_url</tt>, <tt>new_polymorphic_path</tt>
37
+ # * <tt>formatted_polymorphic_url</tt>, <tt>formatted_polymorphic_path</tt>
38
+ #
39
+ # Example usage:
40
+ #
41
+ # edit_polymorphic_path(@post)
42
+ # #=> /posts/1/edit
43
+ #
44
+ # formatted_polymorphic_path([@post, :pdf])
45
+ # #=> /posts/1.pdf
2
46
  module PolymorphicRoutes
47
+ # Constructs a call to a named RESTful route for the given record and returns the
48
+ # resulting URL string. For example:
49
+ #
50
+ # polymorphic_url(post)
51
+ # # calls post_url(post) #=> "http://example.com/posts/1"
52
+ #
53
+ # ==== Options
54
+ # * <tt>:action</tt> -- specifies the action prefix for the named route:
55
+ # <tt>:new</tt>, <tt>:edit</tt> or <tt>:formatted</tt>. Default is no prefix.
56
+ # * <tt>:routing_type</tt> -- <tt>:path</tt> or <tt>:url</tt> (default <tt>:url</tt>).
57
+ #
58
+ # ==== Examples
59
+ #
60
+ # # an Article record
61
+ # polymorphic_url(record) #-> article_url(record)
62
+ #
63
+ # # a Comment record
64
+ # polymorphic_url(record) #-> comment_url(record)
65
+ #
66
+ # # it recognizes new records and maps to the collection
67
+ # record = Comment.new
68
+ # polymorphic_url(record) #-> comments_url()
69
+ #
3
70
  def polymorphic_url(record_or_hash_or_array, options = {})
4
- record = extract_record(record_or_hash_or_array)
5
-
71
+ record = extract_record(record_or_hash_or_array)
72
+ format = (options[:action].to_s == "formatted" and record_or_hash_or_array.pop)
6
73
  namespace = extract_namespace(record_or_hash_or_array)
7
74
 
8
75
  args = case record_or_hash_or_array
@@ -11,9 +78,11 @@ module ActionController
11
78
  else [ record_or_hash_or_array ]
12
79
  end
13
80
 
81
+ args << format if format
82
+
14
83
  inflection =
15
84
  case
16
- when options[:action] == "new"
85
+ when options[:action].to_s == "new"
17
86
  args.pop
18
87
  :singular
19
88
  when record.respond_to?(:new_record?) && record.new_record?
@@ -27,8 +96,11 @@ module ActionController
27
96
  send!(named_route, *args)
28
97
  end
29
98
 
30
- def polymorphic_path(record_or_hash_or_array)
31
- polymorphic_url(record_or_hash_or_array, :routing_type => :path)
99
+ # Returns the path component of a URL for the given record. It uses
100
+ # <tt>polymorphic_url</tt> with <tt>:routing_type => :path</tt>.
101
+ def polymorphic_path(record_or_hash_or_array, options = {})
102
+ options[:routing_type] = :path
103
+ polymorphic_url(record_or_hash_or_array, options)
32
104
  end
33
105
 
34
106
  %w(edit new formatted).each do |action|
@@ -43,26 +115,29 @@ module ActionController
43
115
  EOT
44
116
  end
45
117
 
46
-
47
118
  private
48
119
  def action_prefix(options)
49
120
  options[:action] ? "#{options[:action]}_" : ""
50
121
  end
51
122
 
52
123
  def routing_type(options)
53
- "#{options[:routing_type] || "url"}"
124
+ options[:routing_type] || :url
54
125
  end
55
126
 
56
127
  def build_named_route_call(records, namespace, inflection, options = {})
57
- records = Array.new([extract_record(records)]) unless records.is_a?(Array)
58
- base_segment = "#{RecordIdentifier.send!("#{inflection}_class_name", records.pop)}_"
59
-
60
- method_root = records.reverse.inject(base_segment) do |string, name|
61
- segment = "#{RecordIdentifier.send!("singular_class_name", name)}_"
62
- segment << string
128
+ unless records.is_a?(Array)
129
+ record = extract_record(records)
130
+ route = ''
131
+ else
132
+ record = records.pop
133
+ route = records.inject("") do |string, parent|
134
+ string << "#{RecordIdentifier.send!("singular_class_name", parent)}_"
135
+ end
63
136
  end
64
137
 
65
- action_prefix(options) + namespace + method_root + routing_type(options)
138
+ route << "#{RecordIdentifier.send!("#{inflection}_class_name", record)}_"
139
+
140
+ action_prefix(options) + namespace + route + routing_type(options).to_s
66
141
  end
67
142
 
68
143
  def extract_record(record_or_hash_or_array)
@@ -78,7 +153,7 @@ module ActionController
78
153
  if record_or_hash_or_array.is_a?(Array)
79
154
  record_or_hash_or_array.delete_if do |record_or_namespace|
80
155
  if record_or_namespace.is_a?(String) || record_or_namespace.is_a?(Symbol)
81
- namespace << "#{record_or_namespace.to_s}_"
156
+ namespace << "#{record_or_namespace}_"
82
157
  end
83
158
  end
84
159
  end
@@ -53,15 +53,15 @@ module ActionController
53
53
  [ prefix, singular_class_name(record_or_class) ].compact * '_'
54
54
  end
55
55
 
56
- # The DOM class convention is to use the singular form of an object or class with the id following an underscore.
56
+ # The DOM id convention is to use the singular form of an object or class with the id following an underscore.
57
57
  # If no id is found, prefix with "new_" instead. Examples:
58
58
  #
59
- # dom_class(Post.new(:id => 45)) # => "post_45"
60
- # dom_class(Post.new) # => "new_post"
59
+ # dom_id(Post.new(:id => 45)) # => "post_45"
60
+ # dom_id(Post.new) # => "new_post"
61
61
  #
62
62
  # If you need to address multiple instances of the same class in the same view, you can prefix the dom_id:
63
63
  #
64
- # dom_class(Post.new(:id => 45), :edit) # => "edit_post_45"
64
+ # dom_id(Post.new(:id => 45), :edit) # => "edit_post_45"
65
65
  def dom_id(record, prefix = nil)
66
66
  prefix ||= 'new' unless record.id
67
67
  [ prefix, singular_class_name(record), record.id ].compact * '_'