actionpack 1.5.0 → 1.5.1

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 CHANGED
@@ -1,3 +1,38 @@
1
+ *1.5.1* (7th March, 2005)
2
+
3
+ * Fixed that the routes.rb file wouldn't be found on symlinked setups due to File.expand_path #793 [piotr@t-p-l.com]
4
+
5
+ * Changed ActiveRecordStore to use Marshal instead of YAML as the latter proved troublesome in persisting circular dependencies. Updating existing applications MUST clear their existing session table from data to start using this updated store #739 [Jamis Buck]
6
+
7
+ * Added shortcut :id assignment to render_component and friends (before you had to go through :params) #784 [Lucas Carlson]
8
+
9
+ * Fixed that map.connect should convert arguments to strings #780 [Nicholas Seckar]
10
+
11
+ * Added UrlHelper#link_to_if/link_to_unless to enable other conditions that just link_to_unless_current #757 [mindel]
12
+
13
+ * Fixed that single quote was not escaped in a UrlHelper#link_to javascript confirm #549 [Scott Barron]
14
+
15
+ * Removed the default border on link_image_to (it broke xhtml strict) -- can be specified with :border => 0 #517 [?/caleb]
16
+
17
+ * Fixed that form helpers would treat string and symbol keys differently in html_options (and possibly create duplicate entries) #112 [bitsweat]
18
+
19
+ * Fixed that broken pipe errors (clients disconnecting in mid-request) could bring down a fcgi process
20
+
21
+ * Added the original exception message to session recall errors (so you can see which class wasnt required)
22
+
23
+ * Fixed that RAILS_ROOT might not be defined when AP was loaded, so do a late initialization of the ROUTE_FILE #761 [Scott Barron]
24
+
25
+ * Fix request.path_info and clear up LoadingModule behavior #754 [Nicholas Seckar]
26
+
27
+ * Fixed caching to be aware of extensions (so you can cache files like api.wsdl or logo.png) #734 [Nicholas Seckar]
28
+
29
+ * Fixed that Routes would raise NameErrors if a controller component contains characters that are not valid constant names #733 [Nicholas Seckar]
30
+
31
+ * Added PATH_INFO access from the request that allows urls like the following to be interpreted by rails: http://www.example.com/dispatcher.cgi/controller/action -- that makes it possible to use rails as a CGI under lighttpd and would also allow (for example) Rublog to be ported to rails without breaking existing links to Rublog-powered blogs. #728 [Jamis Buck]
32
+
33
+ * Fixed that caching the root would result in .html not index.html #731, #734 [alisdair/Nicholas Seckar]
34
+
35
+
1
36
  *1.5.0* (24th February, 2005)
2
37
 
3
38
  * Added Routing as a replacement for mod_rewrite pretty urls [Nicholas Seckar]. Read more in ActionController::Base.url_for and on http://manuals.rubyonrails.com/read/book/9
@@ -22,16 +22,13 @@
22
22
  #++
23
23
 
24
24
  $:.unshift(File.dirname(__FILE__))
25
+ $:.unshift(File.dirname(__FILE__) + "/../../activesupport/lib")
25
26
 
26
27
  begin
27
- require 'active_support'
28
+ require 'active_support'
28
29
  rescue LoadError
29
- begin
30
- require File.dirname(__FILE__) + '/../../activesupport/lib/active_support'
31
- rescue LoadError
32
- require 'rubygems'
33
- require_gem 'activesupport'
34
- end
30
+ require 'rubygems'
31
+ require_gem 'activesupport'
35
32
  end
36
33
 
37
34
  require 'action_controller/base'
@@ -2,9 +2,6 @@ require 'action_controller/request'
2
2
  require 'action_controller/response'
3
3
  require 'action_controller/routing'
4
4
  require 'action_controller/url_rewriter'
5
- require 'active_support/class_attribute_accessors'
6
- require 'active_support/class_inheritable_attributes'
7
- require 'active_support/inflector'
8
5
  require 'drb'
9
6
 
10
7
  module ActionController #:nodoc:
@@ -90,7 +90,9 @@ module ActionController #:nodoc:
90
90
 
91
91
  private
92
92
  def page_cache_file(path)
93
- (path.empty? ? "/index" : path) + ".html"
93
+ name = ((path.empty? || path == "/") ? "/index" : path)
94
+ name << '.html' unless (name.split('/').last || name).include? '.'
95
+ return name
94
96
  end
95
97
 
96
98
  def page_cache_path(path)
@@ -86,7 +86,7 @@ module ActionController #:nodoc:
86
86
  ActionController::SessionRestoreError,
87
87
  "Session contained objects where the class definition wasn't available. " +
88
88
  "Remember to require classes for all objects kept in the session. " +
89
- "The session has been deleted."
89
+ "The session has been deleted. (Original exception: #{e.message} [#{e.class}])"
90
90
  )
91
91
  end
92
92
  end
@@ -120,14 +120,19 @@ module ActionController #:nodoc:
120
120
  convert_content_type!(@headers)
121
121
  $stdout.binmode if $stdout.respond_to?(:binmode)
122
122
  $stdout.sync = false
123
- print @cgi.header(@headers)
123
+
124
+ begin
125
+ print @cgi.header(@headers)
124
126
 
125
- if @cgi.send(:env_table)['REQUEST_METHOD'] == 'HEAD'
126
- return
127
- elsif @body.respond_to?(:call)
128
- @body.call(self)
129
- else
130
- print @body
127
+ if @cgi.send(:env_table)['REQUEST_METHOD'] == 'HEAD'
128
+ return
129
+ elsif @body.respond_to?(:call)
130
+ @body.call(self)
131
+ else
132
+ print @body
133
+ end
134
+ rescue Errno::EPIPE => e
135
+ # lost connection to the FCGI process -- ignore the output, then
131
136
  end
132
137
  end
133
138
 
@@ -6,13 +6,13 @@ module ActionController #:nodoc:
6
6
  # # Performs a method and then lets hello_world output its render
7
7
  # def delegate_action
8
8
  # do_other_stuff_before_hello_world
9
- # render_component :controller => "greeter", :action => "hello_world"
9
+ # render_component :controller => "greeter", :action => "hello_world", :params => { "person" => "david" }
10
10
  # end
11
11
  # end
12
12
  #
13
13
  # class GreeterController < ActionController::Base
14
14
  # def hello_world
15
- # render_text "Hello World!"
15
+ # render_text "#{@params['person']} says, Hello World!"
16
16
  # end
17
17
  # end
18
18
  #
@@ -54,7 +54,7 @@ module ActionController #:nodoc:
54
54
  request_for_component = @request.dup
55
55
  request_for_component.send(
56
56
  :instance_variable_set, :@parameters,
57
- (options[:params] || {}).merge({ "controller" => options[:controller], "action" => options[:action] })
57
+ (options[:params] || {}).merge({ "controller" => options[:controller], "action" => options[:action], "id" => options[:id] })
58
58
  )
59
59
  return request_for_component
60
60
  end
@@ -77,6 +77,10 @@ module ActionController
77
77
  (%r{^\w+\://[^/]+(/.*|$)$} =~ env['REQUEST_URI']) ? $1 : env['REQUEST_URI'] # Remove domain, which webrick puts into the request_uri.
78
78
  end
79
79
 
80
+ def path_info
81
+ (/^(.*)\.html$/ =~ env['PATH_INFO']) ? $1 : env['PATH_INFO']
82
+ end
83
+
80
84
  def protocol
81
85
  env["HTTPS"] == "on" ? 'https://' : 'http://'
82
86
  end
@@ -86,7 +90,7 @@ module ActionController
86
90
  end
87
91
 
88
92
  def path
89
- path = request_uri ? request_uri.split('?').first : ''
93
+ (path_info && !path_info.empty?) ? path_info : (request_uri ? request_uri.split('?').first : '')
90
94
  end
91
95
 
92
96
  def port
@@ -1,8 +1,6 @@
1
1
  module ActionController
2
2
  # See http://manuals.rubyonrails.com/read/chapter/65
3
3
  module Routing
4
- ROUTE_FILE = defined?(RAILS_ROOT) ? File.expand_path(File.join(RAILS_ROOT, 'config', 'routes')) : nil
5
-
6
4
  class Route #:nodoc:
7
5
  attr_reader :defaults # The defaults hash
8
6
 
@@ -17,7 +15,7 @@ module ActionController
17
15
  raise ArgumentError, "Regexp requirement on #{k}, but #{k} is not in this route's path!" unless @items.include? k
18
16
  @requirements[k] = v
19
17
  else
20
- (@items.include?(k) ? @defaults : @requirements)[k] = v
18
+ (@items.include?(k) ? @defaults : @requirements)[k] = (v.nil? ? nil : v.to_s)
21
19
  end
22
20
  end
23
21
 
@@ -134,6 +132,7 @@ module ActionController
134
132
  def eat_path_to_controller(path)
135
133
  path.inject([Controllers, 1]) do |(mod, length), name|
136
134
  name = name.camelize
135
+ return nil, nil unless /^[A-Z][_a-zA-Z\d]*$/ =~ name
137
136
  controller_name = name + "Controller"
138
137
  return mod.const_get(controller_name), path[length..-1] if mod.const_available? controller_name
139
138
  return nil, nil unless mod.const_available? name
@@ -281,7 +280,8 @@ module ActionController
281
280
 
282
281
  def reload
283
282
  begin
284
- require_dependency(ROUTE_FILE) if ROUTE_FILE
283
+ route_file = defined?(RAILS_ROOT) ? File.join(RAILS_ROOT, 'config', 'routes') : nil
284
+ require_dependency(route_file) if route_file
285
285
  rescue LoadError, ScriptError => e
286
286
  raise RoutingError, "Cannot load config/routes.rb:\n #{e.message}"
287
287
  ensure # Ensure that there is at least one route:
@@ -3,21 +3,25 @@ begin
3
3
  require 'active_record'
4
4
  require 'cgi'
5
5
  require 'cgi/session'
6
+ require 'base64'
6
7
 
7
8
  # Contributed by Tim Bates
8
9
  class CGI
9
10
  class Session
10
- # ActiveRecord database based session storage class.
11
+ # Active Record database-based session storage class.
11
12
  #
12
13
  # Implements session storage in a database using the ActiveRecord ORM library. Assumes that the database
13
14
  # has a table called +sessions+ with columns +id+ (numeric, primary key), +sessid+ and +data+ (text).
14
- # The session data is stored in the +data+ column in YAML format; the user is responsible for ensuring that
15
- # only data that can be YAMLized is stored in the session.
15
+ # The session data is stored in the +data+ column in the binary Marshal format; the user is responsible for ensuring that
16
+ # only data that can be Marshaled is stored in the session.
17
+ #
18
+ # Adding +created_at+ or +updated_at+ datetime columns to the sessions table will enable stamping of the data, which can
19
+ # be used to clear out old sessions.
20
+ #
21
+ # It's highly recommended to have an index on the sessid column to improve performance.
16
22
  class ActiveRecordStore
17
23
  # The ActiveRecord class which corresponds to the database table.
18
24
  class Session < ActiveRecord::Base
19
- serialize :data
20
- # Isn't this class definition beautiful?
21
25
  end
22
26
 
23
27
  # Create a new ActiveRecordStore instance. This constructor is used internally by CGI::Session.
@@ -30,8 +34,8 @@ class CGI
30
34
  # This session's ActiveRecord database row will be created if it does not exist, or opened if it does.
31
35
  def initialize(session, option=nil)
32
36
  ActiveRecord::Base.silence do
33
- @session = Session.find_by_sessid(session.session_id) || Session.new("sessid" => session.session_id, "data" => {})
34
- @data = @session.data
37
+ @session = Session.find_by_sessid(session.session_id) || Session.new("sessid" => session.session_id, "data" => marshalize({}))
38
+ @data = unmarshalize(@session.data)
35
39
  end
36
40
  end
37
41
 
@@ -52,18 +56,27 @@ class CGI
52
56
  # Restore session state from the session's ActiveRecord object.
53
57
  def restore
54
58
  return unless @session
55
- @data = @session.data
59
+ @data = unmarshalize(@session.data)
56
60
  end
57
61
 
58
62
  # Save session state in the session's ActiveRecord object.
59
63
  def update
60
64
  return unless @session
61
- ActiveRecord::Base.silence { @session.update_attribute "data", @data }
65
+ ActiveRecord::Base.silence { @session.update_attribute "data", marshalize(@data) }
62
66
  end
67
+
68
+ private
69
+ def unmarshalize(data)
70
+ Marshal.load(Base64.decode64(data))
71
+ end
72
+
73
+ def marshalize(data)
74
+ Base64.encode64(Marshal.dump(data))
75
+ end
63
76
  end #ActiveRecordStore
64
77
  end #Session
65
78
  end #CGI
66
79
 
67
80
  rescue LoadError
68
81
  # Couldn't load Active Record, so don't make this store available
69
- end
82
+ end
@@ -15,7 +15,7 @@ module ActionView
15
15
  module ActiveRecordHelper
16
16
  # Returns a default input tag for the type of object returned by the method. Example
17
17
  # (title is a VARCHAR column and holds "Hello World"):
18
- # input("post", "title") =>
18
+ # input("post", "title") =>
19
19
  # <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />
20
20
  def input(record_name, method)
21
21
  InstanceTag.new(record_name, method, self).to_tag
@@ -41,7 +41,7 @@ module ActionView
41
41
  # It's possible to specialize the form builder by using a different action name and by supplying another
42
42
  # block renderer. Example (entry is a new record that has a message attribute using VARCHAR):
43
43
  #
44
- # form("entry", :action => "sign", :input_block =>
44
+ # form("entry", :action => "sign", :input_block =>
45
45
  # Proc.new { |record, column| "#{column.human_name}: #{input(record, column.name)}<br />" }) =>
46
46
  #
47
47
  # <form action='/post/sign' method='post'>
@@ -56,16 +56,17 @@ module ActionView
56
56
  # form << content_tag("b", "Department")
57
57
  # form << collection_select("department", "id", @departments, "id", "name")
58
58
  # end
59
- def form(record_name, options = {})
60
- record = instance_eval("@#{record_name}")
59
+ def form(record_name, options = nil)
60
+ options = (options || {}).symbolize_keys
61
+ record = instance_eval("@#{record_name}")
61
62
 
62
63
  options[:action] ||= record.new_record? ? "create" : "update"
63
- action = url_for(:action => options[:action])
64
+ action = url_for(:action => options[:action])
64
65
 
65
66
  submit_value = options[:submit_value] || options[:action].gsub(/[^\w]/, '').capitalize
66
-
67
+
67
68
  id_field = record.new_record? ? "" : InstanceTag.new(record_name, "id", self).to_input_field_tag("hidden")
68
-
69
+
69
70
  formtag = %(<form action="#{action}" method="post">#{id_field}) + all_input_tags(record, record_name, options)
70
71
  yield formtag if block_given?
71
72
  formtag + %(<input type="submit" value="#{submit_value}" /></form>)
@@ -73,7 +74,7 @@ module ActionView
73
74
 
74
75
  # Returns a string containing the error message attached to the +method+ on the +object+, if one exists.
75
76
  # This error message is wrapped in a DIV tag, which can be specialized to include both a +prepend_text+ and +append_text+
76
- # to properly introduce the error and a +css_class+ to style it accordingly. Examples (post has an error message
77
+ # to properly introduce the error and a +css_class+ to style it accordingly. Examples (post has an error message
77
78
  # "can't be empty" on the title attribute):
78
79
  #
79
80
  # <%= error_message_on "post", "title" %> =>
@@ -86,19 +87,20 @@ module ActionView
86
87
  "<div class=\"#{css_class}\">#{prepend_text + (errors.is_a?(Array) ? errors.first : errors) + append_text}</div>"
87
88
  end
88
89
  end
89
-
90
+
90
91
  # Returns a string with a div containing all the error messages for the object located as an instance variable by the name
91
92
  # of <tt>object_name</tt>. This div can be tailored by the following options:
92
93
  #
93
94
  # * <tt>header_tag</tt> - Used for the header of the error div (default: h2)
94
95
  # * <tt>id</tt> - The id of the error div (default: errorExplanation)
95
96
  # * <tt>class</tt> - The class of the error div (default: errorExplanation)
96
- def error_messages_for(object_name, options={})
97
+ def error_messages_for(object_name, options = {})
98
+ options = options.symbolize_keys
97
99
  object = instance_eval "@#{object_name}"
98
100
  unless object.errors.empty?
99
101
  content_tag("div",
100
102
  content_tag(
101
- options[:header_tag] || "h2",
103
+ options[:header_tag] || "h2",
102
104
  "#{pluralize(object.errors.count, "error")} prohibited this #{object_name.gsub("_", " ")} from being saved"
103
105
  ) +
104
106
  content_tag("p", "There were problems with the following fields:") +
@@ -107,7 +109,7 @@ module ActionView
107
109
  )
108
110
  end
109
111
  end
110
-
112
+
111
113
  private
112
114
  def all_input_tags(record, record_name, options)
113
115
  input_block = options[:input_block] || default_input_block
@@ -116,7 +118,7 @@ module ActionView
116
118
 
117
119
  def default_input_block
118
120
  Proc.new { |record, column| "<p><label for=\"#{record}_#{column.name}\">#{column.human_name}</label><br />#{input(record, column.name)}</p>" }
119
- end
121
+ end
120
122
  end
121
123
 
122
124
  class InstanceTag #:nodoc:
@@ -10,15 +10,15 @@ module ActionView
10
10
  # either be <tt>:rss</tt> (default) or <tt>:atom</tt> and the +options+ follow the url_for style of declaring a link target.
11
11
  #
12
12
  # Examples:
13
- # auto_discovery_link_tag # =>
13
+ # auto_discovery_link_tag # =>
14
14
  # <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.curenthost.com/controller/action" />
15
- # auto_discovery_link_tag(:atom) # =>
15
+ # auto_discovery_link_tag(:atom) # =>
16
16
  # <link rel="alternate" type="application/atom+xml" title="ATOM" href="http://www.curenthost.com/controller/action" />
17
- # auto_discovery_link_tag(:rss, :action => "feed") # =>
17
+ # auto_discovery_link_tag(:rss, :action => "feed") # =>
18
18
  # <link rel="alternate" type="application/atom+xml" title="ATOM" href="http://www.curenthost.com/controller/feed" />
19
19
  def auto_discovery_link_tag(type = :rss, options = {})
20
20
  tag(
21
- "link", "rel" => "alternate", "type" => "application/#{type}+xml", "title" => type.to_s.upcase,
21
+ "link", "rel" => "alternate", "type" => "application/#{type}+xml", "title" => type.to_s.upcase,
22
22
  "href" => url_for(options.merge(:only_path => false))
23
23
  )
24
24
  end
@@ -38,7 +38,7 @@ module ActionView
38
38
  content_tag("script", "", "language" => "JavaScript", "type" => "text/javascript", "src" => source)
39
39
  }.join("\n")
40
40
  end
41
-
41
+
42
42
  # Returns a css link tag per source given as argument. Examples:
43
43
  #
44
44
  # stylesheet_link_tag "style" # =>
@@ -48,7 +48,7 @@ module ActionView
48
48
  # <link href="/stylesheets/random.styles" media="screen" rel="Stylesheet" type="text/css" />
49
49
  # <link href="/css/stylish.css" media="screen" rel="Stylesheet" type="text/css" />
50
50
  def stylesheet_link_tag(*sources)
51
- sources.collect { |source|
51
+ sources.collect { |source|
52
52
  source = "/stylesheets/#{source}" unless source.include?("/")
53
53
  source = "#{source}.css" unless source.include?(".")
54
54
  tag("link", "rel" => "Stylesheet", "type" => "text/css", "media" => "screen", "href" => source)
@@ -5,7 +5,7 @@ module ActionView
5
5
  # The Date Helper primarily creates select/option tags for different kinds of dates and date elements. All of the select-type methods
6
6
  # share a number of common options that are as follows:
7
7
  #
8
- # * <tt>:prefix</tt> - overwrites the default prefix of "date" used for the select names. So specifying "birthday" would give
8
+ # * <tt>:prefix</tt> - overwrites the default prefix of "date" used for the select names. So specifying "birthday" would give
9
9
  # birthday[month] instead of date[month] if passed to the select_month method.
10
10
  # * <tt>:include_blank</tt> - set to true if it should be possible to set an empty date.
11
11
  # * <tt>:discard_type</tt> - set to true if you want to discard the type part of the select name. If set to true, the select_month
@@ -13,11 +13,11 @@ module ActionView
13
13
  module DateHelper
14
14
  DEFAULT_PREFIX = "date" unless const_defined?("DEFAULT_PREFIX")
15
15
 
16
- # Reports the approximate distance in time between to Time objects. For example, if the distance is 47 minutes, it'll return
16
+ # Reports the approximate distance in time between to Time objects. For example, if the distance is 47 minutes, it'll return
17
17
  # "about 1 hour". See the source for the complete wording list.
18
18
  def distance_of_time_in_words(from_time, to_time)
19
19
  distance_in_minutes = ((to_time - from_time) / 60).round
20
-
20
+
21
21
  case distance_in_minutes
22
22
  when 0 then "less than a minute"
23
23
  when 1 then "1 minute"
@@ -28,7 +28,7 @@ module ActionView
28
28
  else "#{(distance_in_minutes / 1440).round} days"
29
29
  end
30
30
  end
31
-
31
+
32
32
  # Like distance_of_time_in_words, but where <tt>to_time</tt> is fixed to <tt>Time.now</tt>.
33
33
  def distance_of_time_in_words_to_now(from_time)
34
34
  distance_of_time_in_words(from_time, Time.now)
@@ -48,7 +48,7 @@ module ActionView
48
48
  #
49
49
  # date_select("post", "written_on")
50
50
  # date_select("post", "written_on", :start_year => 1995)
51
- # date_select("post", "written_on", :start_year => 1995, :use_month_numbers => true,
51
+ # date_select("post", "written_on", :start_year => 1995, :use_month_numbers => true,
52
52
  # :discard_day => true, :include_blank => true)
53
53
  # date_select("post", "written_on", :order => [:day, :month, :year])
54
54
  # date_select("user", "birthday", :order => [:month, :day])
@@ -107,7 +107,7 @@ module ActionView
107
107
 
108
108
  0.upto(59) do |minute|
109
109
  minute_options << ((datetime.kind_of?(Fixnum) ? datetime : datetime.min) == minute ?
110
- "<option selected=\"selected\">#{leading_zero_on_single_digits(minute)}</option>\n" :
110
+ "<option selected=\"selected\">#{leading_zero_on_single_digits(minute)}</option>\n" :
111
111
  "<option>#{leading_zero_on_single_digits(minute)}</option>\n"
112
112
  )
113
113
  end
@@ -122,7 +122,7 @@ module ActionView
122
122
 
123
123
  0.upto(23) do |hour|
124
124
  hour_options << ((datetime.kind_of?(Fixnum) ? datetime : datetime.hour) == hour ?
125
- "<option selected=\"selected\">#{leading_zero_on_single_digits(hour)}</option>\n" :
125
+ "<option selected=\"selected\">#{leading_zero_on_single_digits(hour)}</option>\n" :
126
126
  "<option>#{leading_zero_on_single_digits(hour)}</option>\n"
127
127
  )
128
128
  end
@@ -137,18 +137,18 @@ module ActionView
137
137
 
138
138
  1.upto(31) do |day|
139
139
  day_options << ((date.kind_of?(Fixnum) ? date : date.day) == day ?
140
- "<option selected=\"selected\">#{day}</option>\n" :
140
+ "<option selected=\"selected\">#{day}</option>\n" :
141
141
  "<option>#{day}</option>\n"
142
142
  )
143
143
  end
144
144
 
145
145
  select_html("day", day_options, options[:prefix], options[:include_blank], options[:discard_type])
146
146
  end
147
-
147
+
148
148
  # Returns a select tag with options for each of the months January through December with the current month selected.
149
149
  # The month names are presented as keys (what's shown to the user) and the month numbers (1-12) are used as values
150
150
  # (what's submitted to the server). It's also possible to use month numbers for the presentation instead of names --
151
- # set the <tt>:use_month_numbers</tt> key in +options+ to true for this to happen. If you want both numbers and names,
151
+ # set the <tt>:use_month_numbers</tt> key in +options+ to true for this to happen. If you want both numbers and names,
152
152
  # set the <tt>:add_month_numbers</tt> key in +options+ to true. Examples:
153
153
  #
154
154
  # select_month(Date.today) # Will use keys like "January", "March"
@@ -158,7 +158,7 @@ module ActionView
158
158
  month_options = []
159
159
 
160
160
  1.upto(12) do |month_number|
161
- month_name = if options[:use_month_numbers]
161
+ month_name = if options[:use_month_numbers]
162
162
  month_number
163
163
  elsif options[:add_month_numbers]
164
164
  month_number.to_s + " - " + Date::MONTHNAMES[month_number]
@@ -167,16 +167,16 @@ module ActionView
167
167
  end
168
168
 
169
169
  month_options << ((date.kind_of?(Fixnum) ? date : date.month) == month_number ?
170
- %(<option value="#{month_number}" selected="selected">#{month_name}</option>\n) :
170
+ %(<option value="#{month_number}" selected="selected">#{month_name}</option>\n) :
171
171
  %(<option value="#{month_number}">#{month_name}</option>\n)
172
172
  )
173
173
  end
174
174
 
175
175
  select_html("month", month_options, options[:prefix], options[:include_blank], options[:discard_type])
176
176
  end
177
-
177
+
178
178
  # Returns a select tag with options for each of the five years on each side of the current, which is selected. The five year radius
179
- # can be changed using the <tt>:start_year</tt> and <tt>:end_year</tt> keys in the +options+. The <tt>date</tt> can also be substituted
179
+ # can be changed using the <tt>:start_year</tt> and <tt>:end_year</tt> keys in the +options+. The <tt>date</tt> can also be substituted
180
180
  # for a year given as a number. Example:
181
181
  #
182
182
  # select_year(Date.today, :start_year => 1992, :end_year => 2007)
@@ -187,14 +187,14 @@ module ActionView
187
187
 
188
188
  (options[:start_year] || default_start_year).upto(options[:end_year] || default_end_year) do |year|
189
189
  year_options << ((date.kind_of?(Fixnum) ? date : date.year) == year ?
190
- "<option selected=\"selected\">#{year}</option>\n" :
190
+ "<option selected=\"selected\">#{year}</option>\n" :
191
191
  "<option>#{year}</option>\n"
192
192
  )
193
193
  end
194
194
 
195
195
  select_html("year", year_options, options[:prefix], options[:include_blank], options[:discard_type])
196
196
  end
197
-
197
+
198
198
  private
199
199
  def select_html(type, options, prefix = nil, include_blank = false, discard_type = false)
200
200
  select_html = %(<select name="#{prefix || DEFAULT_PREFIX})
@@ -206,7 +206,7 @@ module ActionView
206
206
 
207
207
  return select_html
208
208
  end
209
-
209
+
210
210
  def leading_zero_on_single_digits(number)
211
211
  number > 9 ? number : "0#{number}"
212
212
  end
@@ -217,36 +217,32 @@ module ActionView
217
217
 
218
218
  def to_date_select_tag(options = {})
219
219
  defaults = { :discard_type => true }
220
- options = defaults.merge(options)
221
- options_with_prefix = Proc.new { |position| options.update({ :prefix => "#{@object_name}[#{@method_name}(#{position}i)]" }) }
220
+ options = defaults.merge(options)
221
+ options_with_prefix = Proc.new { |position| options.merge(:prefix => "#{@object_name}[#{@method_name}(#{position}i)]") }
222
222
  date = options[:include_blank] ? (value || 0) : (value || Date.today)
223
223
 
224
224
  date_select = ""
225
-
226
- if options[:month_before_year] # For backwards compatibility
227
- options[:order] = [:month, :year, :day]
228
- end
229
-
225
+ options[:order] = [:month, :year, :day] if options[:month_before_year] # For backwards compatibility
230
226
  options[:order] ||= [:year, :month, :day]
231
227
 
232
228
  position = {:year => 1, :month => 2, :day => 3}
233
-
229
+
234
230
  discard = {}
235
231
  discard[:year] = true if options[:discard_year]
236
232
  discard[:month] = true if options[:discard_month]
237
233
  discard[:day] = true if options[:discard_day] or options[:discard_month]
238
-
234
+
239
235
  options[:order].each do |param|
240
236
  date_select << self.send("select_#{param}", date, options_with_prefix.call(position[param])) unless discard[param]
241
237
  end
242
238
 
243
239
  return date_select
244
240
  end
245
-
241
+
246
242
  def to_datetime_select_tag(options = {})
247
243
  defaults = { :discard_type => true }
248
- options = defaults.merge(options)
249
- options_with_prefix = Proc.new { |position| options.update({ :prefix => "#{@object_name}[#{@method_name}(#{position}i)]" }) }
244
+ options = defaults.merge(options)
245
+ options_with_prefix = Proc.new { |position| options.merge(:prefix => "#{@object_name}[#{@method_name}(#{position}i)]") }
250
246
  datetime = options[:include_blank] ? (value || 0) : (value || Time.now)
251
247
 
252
248
  datetime_select = select_year(datetime, options_with_prefix.call(1))
@@ -254,7 +250,7 @@ module ActionView
254
250
  datetime_select << select_day(datetime, options_with_prefix.call(3)) unless options[:discard_day] || options[:discard_month]
255
251
  datetime_select << " &mdash; " + select_hour(datetime, options_with_prefix.call(4)) unless options[:discard_hour]
256
252
  datetime_select << " : " + select_minute(datetime, options_with_prefix.call(5)) unless options[:discard_minute] || options[:discard_hour]
257
-
253
+
258
254
  return datetime_select
259
255
  end
260
256
  end