aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile2
-rw-r--r--actionpack/lib/action_controller/metal/head.rb3
-rw-r--r--actionpack/lib/action_controller/metal/params_wrapper.rb5
-rw-r--r--actionpack/test/controller/params_wrapper_test.rb17
-rw-r--r--actionpack/test/controller/render_test.rb21
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb4
-rw-r--r--activerecord/lib/active_record/relation.rb2
-rw-r--r--activerecord/test/cases/migration_test.rb10
-rw-r--r--activerecord/test/cases/relations_test.rb4
-rw-r--r--activesupport/CHANGELOG.md66
-rw-r--r--activesupport/lib/active_support/core_ext/class/attribute_accessors.rb134
-rw-r--r--activesupport/lib/active_support/core_ext/date_time/calculations.rb11
-rw-r--r--activesupport/lib/active_support/core_ext/time/calculations.rb15
-rw-r--r--activesupport/test/core_ext/date_time_ext_test.rb8
-rw-r--r--activesupport/test/core_ext/time_ext_test.rb8
-rw-r--r--activesupport/test/core_ext/time_with_zone_test.rb14
-rw-r--r--railties/guides/source/caching_with_rails.textile18
-rw-r--r--railties/lib/rails/engine/commands.rb4
19 files changed, 309 insertions, 43 deletions
diff --git a/Gemfile b/Gemfile
index 103dd1bd6c..a11091f075 100644
--- a/Gemfile
+++ b/Gemfile
@@ -47,7 +47,7 @@ instance_eval File.read '.Gemfile' if File.exists? '.Gemfile'
platforms :mri do
group :test do
- gem 'ruby-prof' if RUBY_VERSION < '1.9.3'
+ gem 'ruby-prof', '0.10.8' if RUBY_VERSION < '1.9.3'
end
end
diff --git a/actionpack/lib/action_controller/metal/head.rb b/actionpack/lib/action_controller/metal/head.rb
index a618533d09..671053566d 100644
--- a/actionpack/lib/action_controller/metal/head.rb
+++ b/actionpack/lib/action_controller/metal/head.rb
@@ -20,6 +20,7 @@ module ActionController
options, status = status, nil if status.is_a?(Hash)
status ||= options.delete(:status) || :ok
location = options.delete(:location)
+ content_type = options.delete(:content_type)
options.each do |key, value|
headers[key.to_s.dasherize.split('-').each { |v| v[0] = v[0].chr.upcase }.join('-')] = value.to_s
@@ -27,7 +28,7 @@ module ActionController
self.status = status
self.location = url_for(location) if location
- self.content_type = Mime[formats.first] if formats
+ self.content_type = content_type || (Mime[formats.first] if formats)
self.response_body = " "
end
end
diff --git a/actionpack/lib/action_controller/metal/params_wrapper.rb b/actionpack/lib/action_controller/metal/params_wrapper.rb
index 5c28a8074f..1ab436a205 100644
--- a/actionpack/lib/action_controller/metal/params_wrapper.rb
+++ b/actionpack/lib/action_controller/metal/params_wrapper.rb
@@ -167,8 +167,9 @@ module ActionController
unless options[:include] || options[:exclude]
model ||= _default_wrap_model
- if model.respond_to?(:accessible_attributes) && model.accessible_attributes.present?
- options[:include] = model.accessible_attributes.to_a
+ role = options.has_key?(:as) ? options[:as] : :default
+ if model.respond_to?(:accessible_attributes) && model.accessible_attributes(role).present?
+ options[:include] = model.accessible_attributes(role).to_a
elsif model.respond_to?(:attribute_names) && model.attribute_names.present?
options[:include] = model.attribute_names
end
diff --git a/actionpack/test/controller/params_wrapper_test.rb b/actionpack/test/controller/params_wrapper_test.rb
index c4d2614200..fa1608b9df 100644
--- a/actionpack/test/controller/params_wrapper_test.rb
+++ b/actionpack/test/controller/params_wrapper_test.rb
@@ -174,7 +174,7 @@ class ParamsWrapperTest < ActionController::TestCase
def test_accessible_wrapped_keys_from_matching_model
User.expects(:respond_to?).with(:accessible_attributes).returns(true)
- User.expects(:accessible_attributes).twice.returns(["username"])
+ User.expects(:accessible_attributes).with(:default).twice.returns(["username"])
with_default_wrapper_options do
@request.env['CONTENT_TYPE'] = 'application/json'
@@ -186,7 +186,7 @@ class ParamsWrapperTest < ActionController::TestCase
def test_accessible_wrapped_keys_from_specified_model
with_default_wrapper_options do
Person.expects(:respond_to?).with(:accessible_attributes).returns(true)
- Person.expects(:accessible_attributes).twice.returns(["username"])
+ Person.expects(:accessible_attributes).with(:default).twice.returns(["username"])
UsersController.wrap_parameters Person
@@ -195,6 +195,19 @@ class ParamsWrapperTest < ActionController::TestCase
assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'person' => { 'username' => 'sikachu' }})
end
end
+
+ def test_accessible_wrapped_keys_with_role_from_specified_model
+ with_default_wrapper_options do
+ Person.expects(:respond_to?).with(:accessible_attributes).returns(true)
+ Person.expects(:accessible_attributes).with(:admin).twice.returns(["username"])
+
+ UsersController.wrap_parameters Person, :as => :admin
+
+ @request.env['CONTENT_TYPE'] = 'application/json'
+ post :parse, { 'username' => 'sikachu', 'title' => 'Developer' }
+ assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'person' => { 'username' => 'sikachu' }})
+ end
+ end
def test_not_wrapping_abstract_model
User.expects(:respond_to?).with(:accessible_attributes).returns(false)
diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb
index 85abf3248d..b4ef22ecf7 100644
--- a/actionpack/test/controller/render_test.rb
+++ b/actionpack/test/controller/render_test.rb
@@ -495,6 +495,14 @@ class TestController < ActionController::Base
render :text => "hello world!"
end
+ def head_created
+ head :created
+ end
+
+ def head_created_with_application_json_content_type
+ head :created, :content_type => "application/json"
+ end
+
def head_with_location_header
head :location => "/foo"
end
@@ -1172,6 +1180,19 @@ class RenderTest < ActionController::TestCase
assert_equal "<html>\n <p>Hello</p>\n</html>\n", @response.body
end
+ def test_head_created
+ post :head_created
+ assert_blank @response.body
+ assert_response :created
+ end
+
+ def test_head_created_with_application_json_content_type
+ post :head_created_with_application_json_content_type
+ assert_blank @response.body
+ assert_equal "application/json", @response.content_type
+ assert_response :created
+ end
+
def test_head_with_location_header
get :head_with_location_header
assert_blank @response.body
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
index c3aba63e1c..08c3917d7e 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -269,13 +269,15 @@ module ActiveRecord
# remove_column(:suppliers, :qualification)
# remove_columns(:suppliers, :qualification, :experience)
def remove_column(table_name, *column_names)
- if column_names.first.kind_of?(Enumerable)
+ if column_names.flatten!
message = 'Passing array to remove_columns is deprecated, please use ' +
'multiple arguments, like: `remove_columns(:posts, :foo, :bar)`'
ActiveSupport::Deprecation.warn message, caller
end
- columns_for_remove(table_name, *column_names).each {|column_name| execute "ALTER TABLE #{quote_table_name(table_name)} DROP #{column_name}" }
+ columns_for_remove(table_name, *column_names).each do |column_name|
+ execute "ALTER TABLE #{quote_table_name(table_name)} DROP #{column_name}"
+ end
end
alias :remove_columns :remove_column
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index 91929f80d2..00f74318c0 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -408,13 +408,13 @@ module ActiveRecord
def remove_column(table_name, *column_names) #:nodoc:
raise ArgumentError.new("You must specify at least one column name. Example: remove_column(:people, :first_name)") if column_names.empty?
- if column_names.first.kind_of?(Enumerable)
+ if column_names.flatten!
message = 'Passing array to remove_columns is deprecated, please use ' +
'multiple arguments, like: `remove_columns(:posts, :foo, :bar)`'
ActiveSupport::Deprecation.warn message, caller
end
- column_names.flatten.each do |column_name|
+ column_names.each do |column_name|
alter_table(table_name) do |definition|
definition.columns.delete(definition[column_name])
end
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index 8c56072337..4b3b30d6ed 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -403,6 +403,8 @@ module ActiveRecord
# If you need to destroy dependent associations or call your <tt>before_*</tt> or
# +after_destroy+ callbacks, use the +destroy_all+ method instead.
def delete_all(conditions = nil)
+ raise ActiveRecordError.new("delete_all doesn't support limit scope") if self.limit_value
+
IdentityMap.repository[symbolized_base_class] = {} if IdentityMap.enabled?
if conditions
where(conditions).delete_all
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index 8dde6c6b5a..a448e0af9d 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -874,9 +874,17 @@ if ActiveRecord::Base.connection.supports_migrations?
end
def test_remove_column_with_array_as_an_argument_is_deprecated
+ ActiveRecord::Base.connection.create_table(:hats) do |table|
+ table.column :hat_name, :string, :limit => 100
+ table.column :hat_size, :integer
+ table.column :hat_style, :string, :limit => 100
+ end
+
assert_deprecated /Passing array to remove_columns is deprecated/ do
- Person.connection.remove_column("people", ["last_name", "description"])
+ Person.connection.remove_column("hats", ["hat_name", "hat_size"])
end
+ ensure
+ ActiveRecord::Base.connection.drop_table(:hats)
end
def test_change_type_of_not_null_column
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index bf2807c384..fc39e67e3d 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -643,6 +643,10 @@ class RelationTest < ActiveRecord::TestCase
assert davids.loaded?
end
+ def test_delete_all_limit_error
+ assert_raises(ActiveRecord::ActiveRecordError) { Author.limit(10).delete_all }
+ end
+
def test_select_argument_error
assert_raises(ArgumentError) { Developer.select }
end
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 169f4b8077..8d8a9d8ad8 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,11 +1,19 @@
+## Rails 3.2.4 (unreleased) ##
+
+* Added #beginning_of_hour and #end_of_hour to Time and DateTime core
+ extensions. *Mark J. Titorenko*
+
+
## Rails 3.2.3 (March 30, 2012) ##
* No changes.
+
## Rails 3.2.2 (March 1, 2012) ##
* No changes.
+
## Rails 3.2.1 (January 26, 2012) ##
* Documentation fixes and improvements.
@@ -90,6 +98,36 @@
filehandle, or tune your filesystem.
+## Rails 3.1.4 (March 1, 2012) ##
+
+* No changes
+
+
+## Rails 3.1.3 (November 20, 2011) ##
+
+* No changes
+
+
+## Rails 3.1.2 (November 18, 2011) ##
+
+* No changes
+
+
+## Rails 3.1.1 (October 7, 2011) ##
+
+* ruby193: String#prepend is also unsafe *Akira Matsuda*
+
+* Fix obviously breakage of Time.=== for Time subclasses *jeremyevans*
+
+* Added fix so that file store does not raise an exception when cache dir does
+ not exist yet. This can happen if a delete_matched is called before anything
+ is saved in the cache. *Philippe Huibonhoa*
+
+* Fixed performance issue where TimeZone lookups would require tzinfo each time *Tim Lucas*
+
+* ActiveSupport::OrderedHash is now marked as extractable when using Array#extract_options! *Prem Sichanugrist*
+
+
## Rails 3.1.0 (August 30, 2011) ##
* ActiveSupport::Dependencies#load and ActiveSupport::Dependencies#require now
@@ -132,12 +170,38 @@
* JSON decoding now uses the multi_json gem which also vendors a json engine called OkJson. The yaml backend has been removed in favor of OkJson as a default engine for 1.8.x, while the built in 1.9.x json implementation will be used by default. *Josh Kalderimis*
+## Rails 3.0.12 (March 1, 2012) ##
+
+* No changes.
+
+
+## Rails 3.0.11 (November 18, 2011) ##
+
+* No changes.
+
+
+## Rails 3.0.10 (August 16, 2011) ##
+
+* Delayed backtrace scrubbing in `load_missing_constant` until we actually
+ raise the exception
+
+
+## Rails 3.0.9 (June 16, 2011) ##
+
+* No changes.
+
+
+## Rails 3.0.8 (June 7, 2011) ##
+
+* No changes.
+
+
## Rails 3.0.7 (April 18, 2011) ##
* Hash.from_xml no longer loses attributes on tags containing only whitespace *André Arko*
-* Rails 3.0.6 (April 5, 2011)
+## Rails 3.0.6 (April 5, 2011)
* No changes.
diff --git a/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
index 268303aaf2..5369348c26 100644
--- a/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
+++ b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
@@ -2,30 +2,33 @@ require 'active_support/core_ext/array/extract_options'
# Extends the class object with class and instance accessors for class attributes,
# just like the native attr* accessors for instance attributes.
-#
-# Note that unlike +class_attribute+, if a subclass changes the value then that would
-# also change the value for parent class. Similarly if parent class changes the value
-# then that would change the value of subclasses too.
-#
-# class Person
-# cattr_accessor :hair_colors
-# end
-#
-# Person.hair_colors = [:brown, :black, :blonde, :red]
-# Person.hair_colors # => [:brown, :black, :blonde, :red]
-# Person.new.hair_colors # => [:brown, :black, :blonde, :red]
-#
-# To opt out of the instance writer method, pass :instance_writer => false.
-# To opt out of the instance reader method, pass :instance_reader => false.
-# To opt out of both instance methods, pass :instance_accessor => false.
-#
-# class Person
-# cattr_accessor :hair_colors, :instance_writer => false, :instance_reader => false
-# end
-#
-# Person.new.hair_colors = [:brown] # => NoMethodError
-# Person.new.hair_colors # => NoMethodError
class Class
+ # Defines a class attribute if it's not defined and creates a reader method that
+ # returns the attribute value.
+ #
+ # class Person
+ # cattr_reader :hair_colors
+ # end
+ #
+ # Person.class_variable_set("@@hair_colors", [:brown, :black])
+ # Person.hair_colors # => [:brown, :black]
+ # Person.new.hair_colors # => [:brown, :black]
+ #
+ # The attribute name must be a valid method name in Ruby.
+ #
+ # class Person
+ # cattr_reader :"1_Badname "
+ # end
+ # # => NameError: invalid attribute name
+ #
+ # If you want to opt out the instance reader method, you can pass <tt>:instance_reader => false</tt>
+ # or <tt>:instance_accessor => false</tt>.
+ #
+ # class Person
+ # cattr_reader :hair_colors, :instance_reader => false
+ # end
+ #
+ # Person.new.hair_colors # => NoMethodError
def cattr_reader(*syms)
options = syms.extract_options!
syms.each do |sym|
@@ -49,6 +52,43 @@ class Class
end
end
+ # Defines a class attribute if it's not defined and creates a writer method to allow
+ # assignment to the attribute.
+ #
+ # class Person
+ # cattr_writer :hair_colors
+ # end
+ #
+ # Person.hair_colors = [:brown, :black]
+ # Person.class_variable_get("@@hair_colors") # => [:brown, :black]
+ # Person.new.hair_colors = [:blonde, :red]
+ # Person.class_variable_get("@@hair_colors") # => [:blonde, :red]
+ #
+ # The attribute name must be a valid method name in Ruby.
+ #
+ # class Person
+ # cattr_writer :"1_Badname "
+ # end
+ # # => NameError: invalid attribute name
+ #
+ # If you want to opt out the instance writer method, pass <tt>:instance_writer => false</tt>
+ # or <tt>:instance_accessor => false</tt>.
+ #
+ # class Person
+ # cattr_writer :hair_colors, :instance_writer => false
+ # end
+ #
+ # Person.new.hair_colors = [:blonde, :red] # => NoMethodError
+ #
+ # Also, you can pass a block to set up the attribute with a default value.
+ #
+ # class Person
+ # cattr_writer :hair_colors do
+ # [:brown, :black, :blonde, :red]
+ # end
+ # end
+ #
+ # Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
def cattr_writer(*syms)
options = syms.extract_options!
syms.each do |sym|
@@ -73,6 +113,54 @@ class Class
end
end
+ # Defines both class and instance accessors for class attributes.
+ #
+ # class Person
+ # cattr_accessor :hair_colors
+ # end
+ #
+ # Person.hair_colors = [:brown, :black, :blonde, :red]
+ # Person.hair_colors # => [:brown, :black, :blonde, :red]
+ # Person.new.hair_colors # => [:brown, :black, :blonde, :red]
+ #
+ # If a subclass changes the value then that would also change the value for
+ # parent class. Similarly if parent class changes the value then that would
+ # change the value of subclasses too.
+ #
+ # class Male < Person
+ # end
+ #
+ # Male.hair_colors << :blue
+ # Person.hair_colors # => [:brown, :black, :blonde, :red, :blue]
+ #
+ # To opt out of the instance writer method, pass <tt>:instance_writer => false</tt>.
+ # To opt out of the instance reader method, pass <tt>:instance_reader => false</tt>.
+ #
+ # class Person
+ # cattr_accessor :hair_colors, :instance_writer => false, :instance_reader => false
+ # end
+ #
+ # Person.new.hair_colors = [:brown] # => NoMethodError
+ # Person.new.hair_colors # => NoMethodError
+ #
+ # Or pass <tt>:instance_accessor => false</tt>, to opt out both instance methods.
+ #
+ # class Person
+ # cattr_accessor :hair_colors, :instance_accessor => false
+ # end
+ #
+ # Person.new.hair_colors = [:brown] # => NoMethodError
+ # Person.new.hair_colors # => NoMethodError
+ #
+ # Also you can pass a block to set up the attribute with a default value.
+ #
+ # class Person
+ # cattr_accessor :hair_colors do
+ # [:brown, :black, :blonde, :red]
+ # end
+ # end
+ #
+ # Person.class_variable_get("@@hair_colors") #=> [:brown, :black, :blonde, :red]
def cattr_accessor(*syms, &blk)
cattr_reader(*syms)
cattr_writer(*syms, &blk)
diff --git a/activesupport/lib/active_support/core_ext/date_time/calculations.rb b/activesupport/lib/active_support/core_ext/date_time/calculations.rb
index 6f3fd416c1..b759dcc824 100644
--- a/activesupport/lib/active_support/core_ext/date_time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/date_time/calculations.rb
@@ -81,6 +81,17 @@ class DateTime
change(:hour => 23, :min => 59, :sec => 59)
end
+ # Returns a new DateTime representing the start of the hour (hh:00:00)
+ def beginning_of_hour
+ change(:min => 0)
+ end
+ alias :at_beginning_of_hour :beginning_of_hour
+
+ # Returns a new DateTime representing the end of the hour (hh:59:59)
+ def end_of_hour
+ change(:min => 59, :sec => 59)
+ end
+
# 1.9.3 defines + and - on DateTime, < 1.9.3 do not.
if DateTime.public_instance_methods(false).include?(:+)
def plus_with_duration(other) #:nodoc:
diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb
index d845cd1c77..5743254462 100644
--- a/activesupport/lib/active_support/core_ext/time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/time/calculations.rb
@@ -218,6 +218,21 @@ class Time
change(:hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
end
+ # Returns a new Time representing the start of the hour (x:00)
+ def beginning_of_hour
+ change(:min => 0)
+ end
+ alias :at_beginning_of_hour :beginning_of_hour
+
+ # Returns a new Time representing the end of the hour, x:59:59.999999 (.999999999 in ruby1.9)
+ def end_of_hour
+ change(
+ :min => 59,
+ :sec => 59,
+ :usec => 999999.999
+ )
+ end
+
# Returns a new Time representing the start of the month (1st of the month, 0:00)
def beginning_of_month
#self - ((self.mday-1).days + self.seconds_since_midnight)
diff --git a/activesupport/test/core_ext/date_time_ext_test.rb b/activesupport/test/core_ext/date_time_ext_test.rb
index 0087163faf..4a9b7c8a4a 100644
--- a/activesupport/test/core_ext/date_time_ext_test.rb
+++ b/activesupport/test/core_ext/date_time_ext_test.rb
@@ -91,6 +91,14 @@ class DateTimeExtCalculationsTest < Test::Unit::TestCase
assert_equal DateTime.civil(2005,2,4,23,59,59), DateTime.civil(2005,2,4,10,10,10).end_of_day
end
+ def test_beginning_of_hour
+ assert_equal DateTime.civil(2005,2,4,19,0,0), DateTime.civil(2005,2,4,19,30,10).beginning_of_hour
+ end
+
+ def test_end_of_hour
+ assert_equal DateTime.civil(2005,2,4,19,59,59), DateTime.civil(2005,2,4,19,30,10).end_of_hour
+ end
+
def test_beginning_of_month
assert_equal DateTime.civil(2005,2,1,0,0,0), DateTime.civil(2005,2,22,10,10,10).beginning_of_month
end
diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb
index 5b0ccb850a..c030611de3 100644
--- a/activesupport/test/core_ext/time_ext_test.rb
+++ b/activesupport/test/core_ext/time_ext_test.rb
@@ -93,6 +93,10 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase
end
end
+ def test_beginning_of_hour
+ assert_equal Time.local(2005,2,4,19,0,0), Time.local(2005,2,4,19,30,10).beginning_of_hour
+ end
+
def test_beginning_of_month
assert_equal Time.local(2005,2,1,0,0,0), Time.local(2005,2,22,10,10,10).beginning_of_month
end
@@ -127,6 +131,10 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase
assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,9,02,0,0,0).end_of_week #sunday
end
+ def test_end_of_hour
+ assert_equal Time.local(2005,2,4,19,59,59,999999.999), Time.local(2005,2,4,19,30,10).end_of_hour
+ end
+
def test_end_of_month
assert_equal Time.local(2005,3,31,23,59,59,999999.999), Time.local(2005,3,20,10,10,10).end_of_month
assert_equal Time.local(2005,2,28,23,59,59,999999.999), Time.local(2005,2,20,10,10,10).end_of_month
diff --git a/activesupport/test/core_ext/time_with_zone_test.rb b/activesupport/test/core_ext/time_with_zone_test.rb
index 9d9e411c28..84afee6c84 100644
--- a/activesupport/test/core_ext/time_with_zone_test.rb
+++ b/activesupport/test/core_ext/time_with_zone_test.rb
@@ -513,6 +513,20 @@ class TimeWithZoneTest < Test::Unit::TestCase
assert_equal "Fri, 31 Dec 1999 23:59:59 EST -05:00", @twz.end_of_day.inspect
end
+ def test_beginning_of_hour
+ utc = Time.utc(2000, 1, 1, 0, 30)
+ twz = ActiveSupport::TimeWithZone.new(utc, @time_zone)
+ assert_equal "Fri, 31 Dec 1999 19:30:00 EST -05:00", twz.inspect
+ assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", twz.beginning_of_hour.inspect
+ end
+
+ def test_end_of_hour
+ utc = Time.utc(2000, 1, 1, 0, 30)
+ twz = ActiveSupport::TimeWithZone.new(utc, @time_zone)
+ assert_equal "Fri, 31 Dec 1999 19:30:00 EST -05:00", twz.inspect
+ assert_equal "Fri, 31 Dec 1999 19:59:59 EST -05:00", twz.end_of_hour.inspect
+ end
+
def test_since
assert_equal "Fri, 31 Dec 1999 19:00:01 EST -05:00", @twz.since(1).inspect
end
diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile
index 6419d32c13..0e811a2527 100644
--- a/railties/guides/source/caching_with_rails.textile
+++ b/railties/guides/source/caching_with_rails.textile
@@ -257,7 +257,9 @@ However, it's important to note that query caches are created at the start of an
h3. Cache Stores
-Rails provides different stores for the cached data created by action and fragment caches. Page caches are always stored on disk.
+Rails provides different stores for the cached data created by <b>action</b> and <b>fragment</b> caches.
+
+TIP: Page caches are always stored on disk.
h4. Configuration
@@ -267,7 +269,7 @@ You can set up your application's default cache store by calling +config.cache_s
config.cache_store = :memory_store
</ruby>
-Alternatively, you can call +ActionController::Base.cache_store+ outside of a configuration block.
+NOTE: Alternatively, you can call +ActionController::Base.cache_store+ outside of a configuration block.
You can access the cache by calling +Rails.cache+.
@@ -294,7 +296,7 @@ h4. ActiveSupport::Cache::MemoryStore
This cache store keeps entries in memory in the same Ruby process. The cache store has a bounded size specified by the +:size+ options to the initializer (default is 32Mb). When the cache exceeds the allotted size, a cleanup will occur and the least recently used entries will be removed.
<ruby>
-ActionController::Base.cache_store = :memory_store, :size => 64.megabytes
+config.cache_store = :memory_store, :size => 64.megabytes
</ruby>
If you're running multiple Ruby on Rails server processes (which is the case if you're using mongrel_cluster or Phusion Passenger), then your Rails server process instances won't be able to share cache data with each other. This cache store is not appropriate for large application deployments, but can work well for small, low traffic sites with only a couple of server processes or for development and test environments.
@@ -306,7 +308,7 @@ h4. ActiveSupport::Cache::FileStore
This cache store uses the file system to store entries. The path to the directory where the store files will be stored must be specified when initializing the cache.
<ruby>
-ActionController::Base.cache_store = :file_store, "/path/to/cache/directory"
+config.cache_store = :file_store, "/path/to/cache/directory"
</ruby>
With this cache store, multiple server processes on the same host can share a cache. Servers processes running on different hosts could share a cache by using a shared file system, but that set up would not be ideal and is not recommended. The cache store is appropriate for low to medium traffic sites that are served off one or two hosts.
@@ -322,7 +324,7 @@ When initializing the cache, you need to specify the addresses for all memcached
The +write+ and +fetch+ methods on this cache accept two additional options that take advantage of features specific to memcached. You can specify +:raw+ to send a value directly to the server with no serialization. The value must be a string or number. You can use memcached direct operation like +increment+ and +decrement+ only on raw values. You can also specify +:unless_exist+ if you don't want memcached to overwrite an existing entry.
<ruby>
-ActionController::Base.cache_store = :mem_cache_store, "cache-1.example.com", "cache-2.example.com"
+config.cache_store = :mem_cache_store, "cache-1.example.com", "cache-2.example.com"
</ruby>
h4. ActiveSupport::Cache::EhcacheStore
@@ -330,7 +332,7 @@ h4. ActiveSupport::Cache::EhcacheStore
If you are using JRuby you can use Terracotta's Ehcache as the cache store for your application. Ehcache is an open source Java cache that also offers an enterprise version with increased scalability, management, and commercial support. You must first install the jruby-ehcache-rails3 gem (version 1.1.0 or later) to use this cache store.
<ruby>
-ActionController::Base.cache_store = :ehcache_store
+config.cache_store = :ehcache_store
</ruby>
When initializing the cache, you may use the +:ehcache_config+ option to specify the Ehcache config file to use (where the default is "ehcache.xml" in your Rails config directory), and the :cache_name option to provide a custom name for your cache (the default is rails_cache).
@@ -359,7 +361,7 @@ h4. ActiveSupport::Cache::NullStore
This cache store implementation is meant to be used only in development or test environments and it never stores anything. This can be very useful in development when you have code that interacts directly with +Rails.cache+, but caching may interfere with being able to see the results of code changes. With this cache store, all +fetch+ and +read+ operations will result in a miss.
<ruby>
-ActionController::Base.cache_store = :null
+config.cache_store = :null_store
</ruby>
h4. Custom Cache Stores
@@ -369,7 +371,7 @@ You can create your own custom cache store by simply extending +ActiveSupport::C
To use a custom cache store, simple set the cache store to a new instance of the class.
<ruby>
-ActionController::Base.cache_store = MyCacheStore.new
+config.cache_store = MyCacheStore.new
</ruby>
h4. Cache Keys
diff --git a/railties/lib/rails/engine/commands.rb b/railties/lib/rails/engine/commands.rb
index b71119af77..ffbc0b4bd6 100644
--- a/railties/lib/rails/engine/commands.rb
+++ b/railties/lib/rails/engine/commands.rb
@@ -34,6 +34,10 @@ The common rails commands available for engines are:
destroy Undo code generated with "generate" (short-cut alias: "d")
All commands can be run with -h for more information.
+
+If you want to run any commands that need to be run in context
+of the application, like `rails server` or `rails console`,
+you should do it from application's directory (typically test/dummy).
EOT
exit(1)
end