actionpack 3.0.0.beta → 3.0.0.beta2
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.
- data/CHANGELOG +291 -260
- data/lib/abstract_controller.rb +5 -2
- data/lib/abstract_controller/assigns.rb +21 -0
- data/lib/abstract_controller/base.rb +13 -5
- data/lib/abstract_controller/collector.rb +2 -0
- data/lib/abstract_controller/helpers.rb +4 -14
- data/lib/abstract_controller/layouts.rb +50 -99
- data/lib/abstract_controller/logger.rb +2 -2
- data/lib/abstract_controller/rendering.rb +105 -173
- data/lib/abstract_controller/view_paths.rb +69 -0
- data/lib/action_controller.rb +1 -2
- data/lib/action_controller/base.rb +10 -32
- data/lib/action_controller/caching.rb +19 -18
- data/lib/action_controller/caching/actions.rb +17 -11
- data/lib/action_controller/caching/fragments.rb +5 -17
- data/lib/action_controller/caching/pages.rb +24 -24
- data/lib/action_controller/caching/sweeping.rb +1 -3
- data/lib/action_controller/deprecated.rb +0 -2
- data/lib/action_controller/deprecated/base.rb +143 -0
- data/lib/action_controller/metal.rb +29 -26
- data/lib/action_controller/metal/compatibility.rb +18 -87
- data/lib/action_controller/metal/cookies.rb +0 -1
- data/lib/action_controller/metal/head.rb +1 -0
- data/lib/action_controller/metal/helpers.rb +2 -2
- data/lib/action_controller/metal/hide_actions.rb +4 -6
- data/lib/action_controller/metal/http_authentication.rb +18 -33
- data/lib/action_controller/metal/implicit_render.rb +21 -0
- data/lib/action_controller/metal/instrumentation.rb +1 -1
- data/lib/action_controller/metal/mime_responds.rb +2 -1
- data/lib/action_controller/metal/rack_delegation.rb +3 -8
- data/lib/action_controller/metal/redirecting.rb +2 -1
- data/lib/action_controller/metal/renderers.rb +4 -2
- data/lib/action_controller/metal/rendering.rb +31 -44
- data/lib/action_controller/metal/request_forgery_protection.rb +41 -4
- data/lib/action_controller/metal/responder.rb +2 -0
- data/lib/action_controller/metal/session_management.rb +0 -36
- data/lib/action_controller/metal/streaming.rb +20 -47
- data/lib/action_controller/metal/testing.rb +0 -1
- data/lib/action_controller/metal/url_for.rb +11 -148
- data/lib/action_controller/middleware.rb +2 -1
- data/lib/action_controller/polymorphic_routes.rb +1 -2
- data/lib/action_controller/railtie.rb +63 -10
- data/lib/action_controller/railties/{subscriber.rb → log_subscriber.rb} +5 -12
- data/lib/action_controller/railties/url_helpers.rb +14 -0
- data/lib/action_controller/record_identifier.rb +20 -1
- data/lib/action_controller/test_case.rb +123 -12
- data/lib/action_dispatch.rb +1 -0
- data/lib/action_dispatch/http/cache.rb +20 -3
- data/lib/action_dispatch/http/filter_parameters.rb +40 -25
- data/lib/action_dispatch/http/mime_negotiation.rb +6 -17
- data/lib/action_dispatch/http/mime_type.rb +2 -7
- data/lib/action_dispatch/http/request.rb +12 -33
- data/lib/action_dispatch/http/response.rb +35 -15
- data/lib/action_dispatch/http/upload.rb +2 -0
- data/lib/action_dispatch/http/url.rb +5 -32
- data/lib/action_dispatch/middleware/callbacks.rb +1 -1
- data/lib/action_dispatch/middleware/cookies.rb +4 -3
- data/lib/action_dispatch/middleware/params_parser.rb +4 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +51 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +1 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +6 -8
- data/lib/action_dispatch/middleware/show_exceptions.rb +0 -14
- data/lib/action_dispatch/middleware/stack.rb +6 -2
- data/lib/action_dispatch/railtie.rb +3 -1
- data/lib/action_dispatch/routing.rb +2 -0
- data/lib/action_dispatch/routing/deprecated_mapper.rb +35 -7
- data/lib/action_dispatch/routing/mapper.rb +134 -48
- data/lib/action_dispatch/routing/route.rb +2 -2
- data/lib/action_dispatch/routing/route_set.rb +217 -158
- data/lib/action_dispatch/routing/url_for.rb +139 -0
- data/lib/action_dispatch/testing/assertions/response.rb +14 -61
- data/lib/action_dispatch/testing/assertions/routing.rb +25 -14
- data/lib/action_dispatch/testing/integration.rb +32 -50
- data/lib/action_dispatch/testing/performance_test.rb +3 -1
- data/lib/action_dispatch/testing/test_process.rb +2 -0
- data/lib/action_dispatch/testing/test_request.rb +2 -0
- data/lib/action_pack/version.rb +4 -3
- data/lib/action_view.rb +11 -6
- data/lib/action_view/base.rb +33 -121
- data/lib/action_view/context.rb +0 -2
- data/lib/action_view/helpers.rb +26 -23
- data/lib/action_view/helpers/active_model_helper.rb +28 -18
- data/lib/action_view/helpers/asset_tag_helper.rb +109 -54
- data/lib/action_view/helpers/atom_feed_helper.rb +2 -2
- data/lib/action_view/helpers/cache_helper.rb +22 -1
- data/lib/action_view/helpers/capture_helper.rb +22 -22
- data/lib/action_view/helpers/date_helper.rb +6 -5
- data/lib/action_view/helpers/form_helper.rb +78 -63
- data/lib/action_view/helpers/form_options_helper.rb +6 -4
- data/lib/action_view/helpers/form_tag_helper.rb +26 -15
- data/lib/action_view/helpers/javascript_helper.rb +90 -10
- data/lib/action_view/helpers/number_helper.rb +315 -118
- data/lib/action_view/helpers/prototype_helper.rb +19 -46
- data/lib/action_view/helpers/record_tag_helper.rb +4 -4
- data/lib/action_view/helpers/tag_helper.rb +7 -24
- data/lib/action_view/helpers/text_helper.rb +8 -7
- data/lib/action_view/helpers/translation_helper.rb +7 -5
- data/lib/action_view/helpers/url_helper.rb +19 -16
- data/lib/action_view/locale/en.yml +45 -6
- data/lib/action_view/lookup_context.rb +190 -0
- data/lib/action_view/paths.rb +22 -63
- data/lib/action_view/railtie.rb +14 -4
- data/lib/action_view/railties/{subscriber.rb → log_subscriber.rb} +1 -1
- data/lib/action_view/render/layouts.rb +73 -0
- data/lib/action_view/render/partials.rb +15 -41
- data/lib/action_view/render/rendering.rb +27 -78
- data/lib/action_view/template.rb +20 -24
- data/lib/action_view/template/error.rb +22 -2
- data/lib/action_view/template/handlers/erb.rb +33 -9
- data/lib/action_view/template/handlers/rjs.rb +1 -2
- data/lib/action_view/template/resolver.rb +46 -104
- data/lib/action_view/template/text.rb +5 -12
- data/lib/action_view/test_case.rb +14 -23
- metadata +83 -40
- data/lib/abstract_controller/compatibility.rb +0 -18
- data/lib/abstract_controller/localized_cache.rb +0 -49
- data/lib/action_controller/metal/configuration.rb +0 -28
- data/lib/action_controller/url_rewriter.rb +0 -76
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'active_support/testing/performance'
|
2
2
|
require 'active_support/testing/default'
|
3
3
|
|
4
|
-
|
4
|
+
begin
|
5
5
|
module ActionDispatch
|
6
6
|
# An integration test that runs a code profiler on your test methods.
|
7
7
|
# Profiling output for combinations of each test method, measurement, and
|
@@ -14,4 +14,6 @@ if defined?(ActiveSupport::Testing::Performance)
|
|
14
14
|
include ActiveSupport::Testing::Default
|
15
15
|
end
|
16
16
|
end
|
17
|
+
rescue NameError
|
18
|
+
$stderr.puts "Specify ruby-prof as application's dependency in Gemfile to run benchmarks."
|
17
19
|
end
|
data/lib/action_pack/version.rb
CHANGED
data/lib/action_view.rb
CHANGED
@@ -37,17 +37,22 @@ module ActionView
|
|
37
37
|
autoload :Helpers
|
38
38
|
|
39
39
|
autoload_under "render" do
|
40
|
+
autoload :Layouts
|
40
41
|
autoload :Partials
|
41
42
|
autoload :Rendering
|
42
43
|
end
|
43
44
|
|
44
|
-
autoload :
|
45
|
-
autoload :
|
46
|
-
autoload :
|
47
|
-
autoload :
|
48
|
-
autoload :
|
45
|
+
autoload :Base
|
46
|
+
autoload :LookupContext
|
47
|
+
autoload :Resolver, 'action_view/template/resolver'
|
48
|
+
autoload :PathResolver, 'action_view/template/resolver'
|
49
|
+
autoload :FileSystemResolver, 'action_view/template/resolver'
|
50
|
+
autoload :PathSet, 'action_view/paths'
|
49
51
|
|
52
|
+
autoload :MissingTemplate, 'action_view/template/error'
|
53
|
+
autoload :ActionViewError, 'action_view/template/error'
|
50
54
|
autoload :TemplateError, 'action_view/template/error'
|
55
|
+
|
51
56
|
autoload :TemplateHandler, 'action_view/template'
|
52
57
|
autoload :TemplateHandlers, 'action_view/template'
|
53
58
|
end
|
@@ -55,7 +60,7 @@ module ActionView
|
|
55
60
|
autoload :TestCase, 'action_view/test_case'
|
56
61
|
end
|
57
62
|
|
63
|
+
require 'active_support/i18n'
|
58
64
|
require 'active_support/core_ext/string/output_safety'
|
59
|
-
require 'action_view/base'
|
60
65
|
|
61
66
|
I18n.load_path << "#{File.dirname(__FILE__)}/action_view/locale/en.yml"
|
data/lib/action_view/base.rb
CHANGED
@@ -1,27 +1,10 @@
|
|
1
1
|
require 'active_support/core_ext/module/attr_internal'
|
2
2
|
require 'active_support/core_ext/module/delegation'
|
3
3
|
require 'active_support/core_ext/class/attribute'
|
4
|
+
require 'active_support/core_ext/array/wrap'
|
4
5
|
|
5
6
|
module ActionView #:nodoc:
|
6
|
-
class
|
7
|
-
end
|
8
|
-
|
9
|
-
class MissingTemplate < ActionViewError #:nodoc:
|
10
|
-
attr_reader :path
|
11
|
-
|
12
|
-
def initialize(paths, path, details, partial)
|
13
|
-
@path = path
|
14
|
-
display_paths = paths.compact.join(":")
|
15
|
-
template_type = if partial
|
16
|
-
"partial"
|
17
|
-
elsif path =~ /layouts/i
|
18
|
-
'layout'
|
19
|
-
else
|
20
|
-
'template'
|
21
|
-
end
|
22
|
-
|
23
|
-
super("Missing #{template_type} #{path} with #{details.inspect} in view path #{display_paths}")
|
24
|
-
end
|
7
|
+
class NonConcattingString < ActiveSupport::SafeBuffer
|
25
8
|
end
|
26
9
|
|
27
10
|
# Action View templates can be written in three ways. If the template file has a <tt>.erb</tt> (or <tt>.rhtml</tt>) extension then it uses a mixture of ERb
|
@@ -173,128 +156,66 @@ module ActionView #:nodoc:
|
|
173
156
|
module Subclasses
|
174
157
|
end
|
175
158
|
|
176
|
-
include Helpers, Rendering, Partials, ::ERB::Util
|
177
|
-
|
178
|
-
def config
|
179
|
-
self.config = DEFAULT_CONFIG unless @config
|
180
|
-
@config
|
181
|
-
end
|
159
|
+
include Helpers, Rendering, Partials, Layouts, ::ERB::Util, Context
|
160
|
+
extend ActiveSupport::Memoizable
|
182
161
|
|
183
|
-
def config=(config)
|
184
|
-
@config = ActiveSupport::OrderedOptions.new.merge(config)
|
185
|
-
end
|
186
|
-
|
187
|
-
extend ActiveSupport::Memoizable
|
188
|
-
|
189
|
-
attr_accessor :base_path, :assigns, :template_extension, :formats
|
190
|
-
attr_internal :captures
|
191
|
-
|
192
|
-
def reset_formats(formats)
|
193
|
-
@formats = formats
|
194
|
-
|
195
|
-
if defined?(AbstractController::HashKey)
|
196
|
-
# This is expensive, but we need to reset this when the format is updated,
|
197
|
-
# which currently only happens
|
198
|
-
Thread.current[:format_locale_key] =
|
199
|
-
AbstractController::HashKey.get(self.class, formats, I18n.locale)
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
class << self
|
204
|
-
delegate :erb_trim_mode=, :to => 'ActionView::Template::Handlers::ERB'
|
205
|
-
delegate :logger, :to => 'ActionController::Base', :allow_nil => true
|
206
|
-
end
|
207
|
-
|
208
|
-
@@debug_rjs = false
|
209
|
-
##
|
210
|
-
# :singleton-method:
|
211
162
|
# Specify whether RJS responses should be wrapped in a try/catch block
|
212
163
|
# that alert()s the caught exception (and then re-raises it).
|
213
164
|
cattr_accessor :debug_rjs
|
165
|
+
@@debug_rjs = false
|
214
166
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
cattr_accessor :cache_template_loading
|
167
|
+
class_attribute :helpers
|
168
|
+
remove_method :helpers
|
169
|
+
attr_reader :helpers
|
219
170
|
|
220
|
-
|
221
|
-
|
222
|
-
true
|
171
|
+
class << self
|
172
|
+
delegate :erb_trim_mode=, :to => 'ActionView::Template::Handlers::ERB'
|
173
|
+
delegate :logger, :to => 'ActionController::Base', :allow_nil => true
|
223
174
|
end
|
224
175
|
|
225
|
-
|
226
|
-
ActionController::Base.allow_concurrency || (cache_template_loading.nil? ? !ActiveSupport::Dependencies.load? : cache_template_loading)
|
227
|
-
end
|
176
|
+
ActiveSupport.run_load_hooks(:action_view, self)
|
228
177
|
|
229
|
-
|
178
|
+
attr_accessor :base_path, :assigns, :template_extension, :lookup_context
|
179
|
+
attr_internal :captures, :request, :controller, :template, :config
|
230
180
|
|
231
|
-
|
232
|
-
|
233
|
-
end
|
181
|
+
delegate :find_template, :template_exists?, :formats, :formats=, :locale, :locale=,
|
182
|
+
:view_paths, :view_paths=, :with_fallbacks, :update_details, :to => :lookup_context
|
234
183
|
|
235
184
|
delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers,
|
236
185
|
:flash, :action_name, :controller_name, :to => :controller
|
237
186
|
|
238
187
|
delegate :logger, :to => :controller, :allow_nil => true
|
239
188
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
def self.process_view_paths(value)
|
245
|
-
ActionView::PathSet.new(Array(value))
|
189
|
+
# TODO: HACK FOR RJS
|
190
|
+
def view_context
|
191
|
+
self
|
246
192
|
end
|
247
193
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
def self.for_controller(controller)
|
252
|
-
@views ||= {}
|
253
|
-
|
254
|
-
# TODO: Decouple this so helpers are a separate concern in AV just like
|
255
|
-
# they are in AC.
|
256
|
-
if controller.class.respond_to?(:_helper_serial)
|
257
|
-
klass = @views[controller.class._helper_serial] ||= Class.new(self) do
|
258
|
-
# Try to make stack traces clearer
|
259
|
-
class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
|
260
|
-
def self.name
|
261
|
-
"ActionView for #{controller.class}"
|
262
|
-
end
|
263
|
-
|
264
|
-
def inspect
|
265
|
-
"#<#{self.class.name}>"
|
266
|
-
end
|
267
|
-
ruby_eval
|
268
|
-
|
269
|
-
if controller.respond_to?(:_helpers)
|
270
|
-
include controller._helpers
|
271
|
-
self.helpers = controller._helpers
|
272
|
-
end
|
273
|
-
end
|
274
|
-
else
|
275
|
-
klass = self
|
276
|
-
end
|
194
|
+
def self.xss_safe? #:nodoc:
|
195
|
+
true
|
196
|
+
end
|
277
197
|
|
278
|
-
|
198
|
+
def self.process_view_paths(value)
|
199
|
+
ActionView::PathSet.new(Array.wrap(value))
|
279
200
|
end
|
280
201
|
|
281
|
-
def initialize(
|
202
|
+
def initialize(lookup_context = nil, assigns_for_first_render = {}, controller = nil, formats = nil) #:nodoc:
|
282
203
|
@config = nil
|
283
|
-
@formats = formats
|
284
204
|
@assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) }
|
285
205
|
@helpers = self.class.helpers || Module.new
|
286
206
|
|
287
207
|
@_controller = controller
|
288
|
-
@
|
208
|
+
@_config = ActiveSupport::InheritableOptions.new(controller.config) if controller && controller.respond_to?(:config)
|
209
|
+
@_content_for = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new }
|
289
210
|
@_virtual_path = nil
|
290
|
-
self.view_paths = view_paths
|
291
|
-
end
|
292
211
|
|
293
|
-
|
294
|
-
|
212
|
+
@lookup_context = lookup_context.is_a?(ActionView::LookupContext) ?
|
213
|
+
lookup_context : ActionView::LookupContext.new(lookup_context)
|
214
|
+
@lookup_context.formats = formats if formats
|
215
|
+
end
|
295
216
|
|
296
|
-
def
|
297
|
-
@
|
217
|
+
def controller_path
|
218
|
+
@controller_path ||= controller && controller.controller_path
|
298
219
|
end
|
299
220
|
|
300
221
|
def punctuate_body!(part)
|
@@ -302,14 +223,5 @@ module ActionView #:nodoc:
|
|
302
223
|
response.body_parts << part
|
303
224
|
nil
|
304
225
|
end
|
305
|
-
|
306
|
-
# Evaluates the local assigns and controller ivars, pushes them to the view.
|
307
|
-
def _evaluate_assigns_and_ivars #:nodoc:
|
308
|
-
if controller
|
309
|
-
variables = controller.instance_variable_names
|
310
|
-
variables -= controller.protected_instance_variables if controller.respond_to?(:protected_instance_variables)
|
311
|
-
variables.each { |name| instance_variable_set(name, controller.instance_variable_get(name)) }
|
312
|
-
end
|
313
|
-
end
|
314
226
|
end
|
315
227
|
end
|
data/lib/action_view/context.rb
CHANGED
@@ -10,8 +10,6 @@ module ActionView
|
|
10
10
|
# In order to work with ActionController, a Context
|
11
11
|
# must implement:
|
12
12
|
#
|
13
|
-
# Context.for_controller[controller] Create a new ActionView instance for a
|
14
|
-
# controller
|
15
13
|
# Context#render_partial[options]
|
16
14
|
# - responsible for setting options[:_template]
|
17
15
|
# - Returns String with the rendered partial
|
data/lib/action_view/helpers.rb
CHANGED
@@ -2,29 +2,32 @@ require 'active_support/benchmarkable'
|
|
2
2
|
|
3
3
|
module ActionView #:nodoc:
|
4
4
|
module Helpers #:nodoc:
|
5
|
-
|
6
|
-
|
7
|
-
autoload :
|
8
|
-
autoload :
|
9
|
-
autoload :
|
10
|
-
autoload :
|
11
|
-
autoload :
|
12
|
-
autoload :
|
13
|
-
autoload :
|
14
|
-
autoload :
|
15
|
-
autoload :
|
16
|
-
autoload :
|
17
|
-
autoload :
|
18
|
-
autoload :
|
19
|
-
autoload :
|
20
|
-
autoload :
|
21
|
-
autoload :
|
22
|
-
autoload :
|
23
|
-
autoload :
|
24
|
-
autoload :
|
25
|
-
autoload :
|
26
|
-
autoload :
|
27
|
-
autoload :
|
5
|
+
extend ActiveSupport::Autoload
|
6
|
+
|
7
|
+
autoload :ActiveModelHelper
|
8
|
+
autoload :AssetTagHelper
|
9
|
+
autoload :AtomFeedHelper
|
10
|
+
autoload :CacheHelper
|
11
|
+
autoload :CaptureHelper
|
12
|
+
autoload :CsrfHelper
|
13
|
+
autoload :DateHelper
|
14
|
+
autoload :DebugHelper
|
15
|
+
autoload :DeprecatedBlockHelpers
|
16
|
+
autoload :FormHelper
|
17
|
+
autoload :FormOptionsHelper
|
18
|
+
autoload :FormTagHelper
|
19
|
+
autoload :JavaScriptHelper, "action_view/helpers/javascript_helper"
|
20
|
+
autoload :NumberHelper
|
21
|
+
autoload :PrototypeHelper
|
22
|
+
autoload :RawOutputHelper
|
23
|
+
autoload :RecordIdentificationHelper
|
24
|
+
autoload :RecordTagHelper
|
25
|
+
autoload :SanitizeHelper
|
26
|
+
autoload :ScriptaculousHelper
|
27
|
+
autoload :TagHelper
|
28
|
+
autoload :TextHelper
|
29
|
+
autoload :TranslationHelper
|
30
|
+
autoload :UrlHelper
|
28
31
|
|
29
32
|
def self.included(base)
|
30
33
|
base.extend(ClassMethods)
|
@@ -3,11 +3,14 @@ require 'action_view/helpers/form_helper'
|
|
3
3
|
require 'active_support/core_ext/class/attribute_accessors'
|
4
4
|
require 'active_support/core_ext/enumerable'
|
5
5
|
require 'active_support/core_ext/kernel/reporting'
|
6
|
+
require 'active_support/core_ext/object/blank'
|
6
7
|
|
7
8
|
module ActionView
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
ActiveSupport.on_load(:action_view) do
|
10
|
+
class ActionView::Base
|
11
|
+
@@field_error_proc = Proc.new{ |html_tag, instance| "<div class=\"fieldWithErrors\">#{html_tag}</div>".html_safe }
|
12
|
+
cattr_accessor :field_error_proc
|
13
|
+
end
|
11
14
|
end
|
12
15
|
|
13
16
|
module Helpers
|
@@ -80,13 +83,13 @@ module ActionView
|
|
80
83
|
record = convert_to_model(record)
|
81
84
|
|
82
85
|
options = options.symbolize_keys
|
83
|
-
options[:action] ||= record.
|
86
|
+
options[:action] ||= record.persisted? ? "update" : "create"
|
84
87
|
action = url_for(:action => options[:action], :id => record)
|
85
88
|
|
86
89
|
submit_value = options[:submit_value] || options[:action].gsub(/[^\w]/, '').capitalize
|
87
90
|
|
88
91
|
contents = form_tag({:action => action}, :method =>(options[:method] || 'post'), :enctype => options[:multipart] ? 'multipart/form-data': nil)
|
89
|
-
contents.safe_concat hidden_field(record_name, :id)
|
92
|
+
contents.safe_concat hidden_field(record_name, :id) if record.persisted?
|
90
93
|
contents.safe_concat all_input_tags(record, record_name, options)
|
91
94
|
yield contents if block_given?
|
92
95
|
contents.safe_concat submit_tag(submit_value)
|
@@ -94,10 +97,10 @@ module ActionView
|
|
94
97
|
end
|
95
98
|
|
96
99
|
# Returns a string containing the error message attached to the +method+ on the +object+ if one exists.
|
97
|
-
# This error message is wrapped in a <tt>DIV</tt> tag
|
98
|
-
#
|
99
|
-
# accordingly. +object+ should either be the name of an
|
100
|
-
# passed in either as a string or a symbol.
|
100
|
+
# This error message is wrapped in a <tt>DIV</tt> tag by default or with <tt>:html_tag</tt> if specified,
|
101
|
+
# which can be extended to include a <tt>:prepend_text</tt> and/or <tt>:append_text</tt> (to properly explain
|
102
|
+
# the error), and a <tt>:css_class</tt> to style it accordingly. +object+ should either be the name of an
|
103
|
+
# instance variable or the actual object. The method can be passed in either as a string or a symbol.
|
101
104
|
# As an example, let's say you have a model <tt>@post</tt> that has an error message on the +title+ attribute:
|
102
105
|
#
|
103
106
|
# <%= error_message_on "post", "title" %>
|
@@ -109,25 +112,28 @@ module ActionView
|
|
109
112
|
# <%= error_message_on "post", "title",
|
110
113
|
# :prepend_text => "Title simply ",
|
111
114
|
# :append_text => " (or it won't work).",
|
115
|
+
# :html_tag => "span",
|
112
116
|
# :css_class => "inputError" %>
|
117
|
+
# # => <span class="inputError">Title simply can't be empty (or it won't work).</span>
|
113
118
|
def error_message_on(object, method, *args)
|
114
119
|
options = args.extract_options!
|
115
120
|
unless args.empty?
|
116
121
|
ActiveSupport::Deprecation.warn('error_message_on takes an option hash instead of separate ' +
|
117
|
-
'prepend_text, append_text, and css_class arguments', caller)
|
122
|
+
'prepend_text, append_text, html_tag, and css_class arguments', caller)
|
118
123
|
|
119
124
|
options[:prepend_text] = args[0] || ''
|
120
125
|
options[:append_text] = args[1] || ''
|
121
|
-
options[:
|
126
|
+
options[:html_tag] = args[2] || 'div'
|
127
|
+
options[:css_class] = args[3] || 'formError'
|
122
128
|
end
|
123
|
-
options.reverse_merge!(:prepend_text => '', :append_text => '', :css_class => 'formError')
|
129
|
+
options.reverse_merge!(:prepend_text => '', :append_text => '', :html_tag => 'div', :css_class => 'formError')
|
124
130
|
|
125
131
|
object = convert_to_model(object)
|
126
132
|
|
127
133
|
if (obj = (object.respond_to?(:errors) ? object : instance_variable_get("@#{object}"))) &&
|
128
|
-
(errors = obj.errors[method])
|
129
|
-
content_tag(
|
130
|
-
|
134
|
+
(errors = obj.errors[method]).presence
|
135
|
+
content_tag(options[:html_tag],
|
136
|
+
(options[:prepend_text].html_safe << errors.first).safe_concat(options[:append_text]),
|
131
137
|
:class => options[:css_class]
|
132
138
|
)
|
133
139
|
else
|
@@ -226,16 +232,16 @@ module ActionView
|
|
226
232
|
|
227
233
|
error_messages = objects.sum do |object|
|
228
234
|
object.errors.full_messages.map do |msg|
|
229
|
-
content_tag(:li,
|
235
|
+
content_tag(:li, msg)
|
230
236
|
end
|
231
|
-
end.join
|
237
|
+
end.join.html_safe
|
232
238
|
|
233
239
|
contents = ''
|
234
240
|
contents << content_tag(options[:header_tag] || :h2, header_message) unless header_message.blank?
|
235
241
|
contents << content_tag(:p, message) unless message.blank?
|
236
242
|
contents << content_tag(:ul, error_messages)
|
237
243
|
|
238
|
-
content_tag(:div, contents, html)
|
244
|
+
content_tag(:div, contents.html_safe, html)
|
239
245
|
end
|
240
246
|
else
|
241
247
|
''
|
@@ -293,6 +299,10 @@ module ActionView
|
|
293
299
|
end
|
294
300
|
end
|
295
301
|
|
302
|
+
def error_message
|
303
|
+
object.errors[@method_name]
|
304
|
+
end
|
305
|
+
|
296
306
|
def column_type
|
297
307
|
object.send(:column_for_attribute, @method_name).type
|
298
308
|
end
|