aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile2
-rw-r--r--actionmailer/CHANGELOG30
-rw-r--r--actionpack/CHANGELOG53
-rw-r--r--actionpack/lib/action_controller/metal/params_wrapper.rb18
-rw-r--r--actionpack/test/activerecord/render_partial_with_record_identification_test.rb2
-rw-r--r--actionpack/test/controller/params_wrapper_test.rb45
-rw-r--r--actionpack/test/controller/request_forgery_protection_test.rb25
-rw-r--r--activemodel/CHANGELOG31
-rw-r--r--activemodel/lib/active_model/serializers/xml.rb1
-rw-r--r--activemodel/test/cases/serializers/xml_serialization_test.rb4
-rw-r--r--activemodel/test/cases/validations/conditional_validation_test.rb24
-rw-r--r--activemodel/test/cases/validations/format_validation_test.rb2
-rw-r--r--activemodel/test/cases/validations/inclusion_validation_test.rb2
-rw-r--r--activemodel/test/cases/validations/length_validation_test.rb30
-rw-r--r--activemodel/test/models/contact.rb4
-rw-r--r--activerecord/CHANGELOG82
-rw-r--r--activerecord/lib/active_record/associations/builder/singular_association.rb13
-rw-r--r--activerecord/lib/active_record/associations/collection_association.rb8
-rw-r--r--activerecord/lib/active_record/associations/has_one_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/through_association.rb5
-rw-r--r--activerecord/lib/active_record/base.rb9
-rw-r--r--activerecord/lib/active_record/fixtures.rb58
-rw-r--r--activerecord/lib/active_record/relation/calculations.rb9
-rw-r--r--activerecord/test/cases/associations/cascaded_eager_loading_test.rb4
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb36
-rw-r--r--activerecord/test/cases/associations/has_one_associations_test.rb18
-rw-r--r--activerecord/test/cases/associations/has_one_through_associations_test.rb4
-rw-r--r--activerecord/test/cases/associations/inner_join_association_test.rb1
-rw-r--r--activerecord/test/cases/associations_test.rb2
-rw-r--r--activerecord/test/cases/base_test.rb11
-rw-r--r--activerecord/test/cases/calculations_test.rb11
-rw-r--r--activerecord/test/cases/fixtures_test.rb4
-rw-r--r--activerecord/test/cases/method_scoping_test.rb22
-rw-r--r--activerecord/test/cases/named_scope_test.rb2
-rw-r--r--activerecord/test/cases/xml_serialization_test.rb5
-rw-r--r--activerecord/test/fixtures/all/people.yml (renamed from activerecord/test/fixtures/all/people.csv)0
-rw-r--r--activerecord/test/fixtures/memberships.yml7
-rw-r--r--activerecord/test/models/bulb.rb2
-rw-r--r--activerecord/test/models/car.rb2
-rw-r--r--activerecord/test/models/member.rb2
-rw-r--r--activerecord/test/models/membership.rb6
-rw-r--r--activerecord/test/schema/schema.rb1
-rw-r--r--activeresource/CHANGELOG30
-rw-r--r--activeresource/test/cases/format_test.rb2
-rw-r--r--activesupport/CHANGELOG30
-rw-r--r--activesupport/README.rdoc2
-rw-r--r--activesupport/lib/active_support/buffered_logger.rb2
-rw-r--r--activesupport/lib/active_support/json/encoding.rb1
-rw-r--r--activesupport/test/buffered_logger_test.rb39
-rw-r--r--activesupport/test/ordered_hash_test.rb1
-rw-r--r--railties/CHANGELOG32
-rw-r--r--railties/guides/source/testing.textile4
-rw-r--r--railties/lib/rails/commands/runner.rb2
-rw-r--r--railties/lib/rails/engine.rb1
-rw-r--r--railties/lib/rails/engine/configuration.rb1
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile4
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt7
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css4
-rw-r--r--railties/lib/rails/generators/rails/app/templates/gitignore1
-rw-r--r--railties/test/application/configuration_test.rb17
-rw-r--r--railties/test/application/initializers/frameworks_test.rb2
-rw-r--r--railties/test/application/middleware_test.rb2
62 files changed, 606 insertions, 177 deletions
diff --git a/Gemfile b/Gemfile
index 23b1a1096b..7199301b90 100644
--- a/Gemfile
+++ b/Gemfile
@@ -10,7 +10,7 @@ end
gem "coffee-script"
gem "sass"
-gem "uglifier"
+gem "uglifier", :git => 'git://github.com/lautis/uglifier.git'
gem "rake", ">= 0.8.7"
gem "mocha", ">= 0.9.8"
diff --git a/actionmailer/CHANGELOG b/actionmailer/CHANGELOG
index 167c1da9c5..d4475bc951 100644
--- a/actionmailer/CHANGELOG
+++ b/actionmailer/CHANGELOG
@@ -2,14 +2,42 @@
* No changes
-*Rails 3.0.2 (unreleased)*
+
+*Rails 3.0.7 (April 18, 2011)*
+
+* remove AM delegating register_observer and register_interceptor to Mail [Josh Kalderimis]
+
+
+*Rails 3.0.6 (April 5, 2011)
+
+* Don't allow i18n to change the minor version, version now set to ~> 0.5.0 [Santiago Pastorino]
+
+
+*Rails 3.0.5 (February 26, 2011)*
+
+* No changes.
+
+
+*Rails 3.0.4 (February 8, 2011)*
+
+* No changes.
+
+
+*Rails 3.0.3 (November 16, 2010)*
+
+* No changes.
+
+
+*Rails 3.0.2 (November 15, 2010)*
* No changes
+
*Rails 3.0.1 (October 15, 2010)*
* No Changes, just a version bump.
+
*Rails 3.0.0 (August 29, 2010)*
* subject is automatically looked up on I18n using mailer_name and action_name as scope as in t(".subject") [JK]
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index 23190ef406..68076b794e 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -133,7 +133,58 @@ tested.
* Add Rack::Cache to the default stack. Create a Rails store that delegates to the Rails cache, so by default, whatever caching layer you are using will be used for HTTP caching. Note that Rack::Cache will be used if you use #expires_in, #fresh_when or #stale with :public => true. Otherwise, the caching rules will apply to the browser only. [Yehuda Katz, Carl Lerche]
-*Rails 3.0.2 (unreleased)*
+*Rails 3.0.7 (April 18, 2011)*
+
+*No changes.
+
+
+*Rails 3.0.6 (April 5, 2011)
+
+* Fixed XSS vulnerability in `auto_link`. `auto_link` no longer marks input as
+ html safe. Please make sure that calls to auto_link() are wrapped in a
+ sanitize(), or a raw() depending on the type of input passed to auto_link().
+ For example:
+
+ <%= sanitize(auto_link(some_user_input)) %>
+
+ Thanks to Torben Schulz for reporting this. The fix can be found here:
+ 61ee3449674c591747db95f9b3472c5c3bd9e84d
+
+* Fixes the output of `rake routes` to be correctly match to the behavior of the application, as the regular expression used to match the path is greedy and won't capture the format part by default [Prem Sichanugrist]
+
+* Fixes an issue with number_to_human when converting values which are less than 1 but greater than -1 [Josh Kalderimis]
+
+* Sensitive query string parameters (specified in config.filter_parameters) will now be filtered out from the request paths in the log file. [Prem Sichanugrist, fxn]
+
+* URL parameters which return nil for to_param are now removed from the query string [Andrew White]
+
+* Don't allow i18n to change the minor version, version now set to ~> 0.5.0 [Santiago Pastorino]
+
+* Make TranslationHelper#translate use the :rescue_format option in I18n 0.5.0 [Sven Fuchs]
+
+* Fix regression: javascript_include_tag shouldn't raise if you register an expansion key with nil or [] value [Santiago Pastorino]
+
+* Fix Action caching bug where an action that has a non-cacheable response always renders a nil response body. It now correctly renders the response body. [Cheah Chu Yeow]
+
+
+*Rails 3.0.5 (February 26, 2011)*
+
+* No changes.
+
+
+*Rails 3.0.4 (February 8, 2011)*
+
+* No changes.
+
+
+*Rails 3.0.3 (November 16, 2010)*
+
+* When ActiveRecord::Base objects are sent to predicate methods, the id of the object should be sent to ARel, not the ActiveRecord::Base object.
+
+* :constraints routing should only do sanity checks against regular expressions. String arguments are OK.
+
+
+*Rails 3.0.2 (November 15, 2010)*
* The helper number_to_currency accepts a new :negative_format option to be able to configure how to render negative amounts. [Don Wilson]
diff --git a/actionpack/lib/action_controller/metal/params_wrapper.rb b/actionpack/lib/action_controller/metal/params_wrapper.rb
index 881af74147..9b27bb8b91 100644
--- a/actionpack/lib/action_controller/metal/params_wrapper.rb
+++ b/actionpack/lib/action_controller/metal/params_wrapper.rb
@@ -136,15 +136,23 @@ module ActionController
# this could be done by trying to find the defined model that has the
# same singularize name as the controller. For example, +UsersController+
# will try to find if the +User+ model exists.
- def _default_wrap_model
+ #
+ # This method also does namespace lookup. Foo::Bar::UsersController will
+ # try to find Foo::Bar::User, Foo::User and finally User.
+ def _default_wrap_model #:nodoc:
model_name = self.name.sub(/Controller$/, '').singularize
begin
model_klass = model_name.constantize
- rescue NameError => e
- unscoped_model_name = model_name.split("::", 2).last
- break if unscoped_model_name == model_name
- model_name = unscoped_model_name
+ rescue NameError, ArgumentError => e
+ if e.message =~ /is not missing constant|uninitialized constant #{model_name}/
+ namespaces = model_name.split("::")
+ namespaces.delete_at(-2)
+ break if namespaces.last == model_name
+ model_name = namespaces.join("::")
+ else
+ raise
+ end
end until model_klass
model_klass
diff --git a/actionpack/test/activerecord/render_partial_with_record_identification_test.rb b/actionpack/test/activerecord/render_partial_with_record_identification_test.rb
index 99f09286ff..97be5a5bb0 100644
--- a/actionpack/test/activerecord/render_partial_with_record_identification_test.rb
+++ b/actionpack/test/activerecord/render_partial_with_record_identification_test.rb
@@ -36,7 +36,7 @@ class RenderPartialWithRecordIdentificationController < ActionController::Base
end
def render_with_record_collection
- @developers = Developer.find(:all)
+ @developers = Developer.all
render :partial => @developers
end
diff --git a/actionpack/test/controller/params_wrapper_test.rb b/actionpack/test/controller/params_wrapper_test.rb
index 548cd02dc0..85464fc780 100644
--- a/actionpack/test/controller/params_wrapper_test.rb
+++ b/actionpack/test/controller/params_wrapper_test.rb
@@ -170,28 +170,36 @@ end
class NamespacedParamsWrapperTest < ActionController::TestCase
module Admin
- class UsersController < ActionController::Base
- class << self
- attr_accessor :last_parameters
- end
-
- def parse
- self.class.last_parameters = request.params.except(:controller, :action)
- head :ok
+ module Users
+ class UsersController < ActionController::Base;
+ class << self
+ attr_accessor :last_parameters
+ end
+
+ def parse
+ self.class.last_parameters = request.params.except(:controller, :action)
+ head :ok
+ end
end
end
end
- class Sample
+ class SampleOne
def self.column_names
["username"]
end
end
- tests Admin::UsersController
+ class SampleTwo
+ def self.column_names
+ ["title"]
+ end
+ end
+
+ tests Admin::Users::UsersController
def teardown
- Admin::UsersController.last_parameters = nil
+ Admin::Users::UsersController.last_parameters = nil
end
def test_derived_name_from_controller
@@ -203,7 +211,7 @@ class NamespacedParamsWrapperTest < ActionController::TestCase
end
def test_namespace_lookup_from_model
- Admin.const_set(:User, Class.new(Sample))
+ Admin.const_set(:User, Class.new(SampleOne))
begin
with_default_wrapper_options do
@request.env['CONTENT_TYPE'] = 'application/json'
@@ -216,20 +224,15 @@ class NamespacedParamsWrapperTest < ActionController::TestCase
end
def test_hierarchy_namespace_lookup_from_model
- # Make sure that we cleanup ::Admin::User
- admin_user_constant = ::Admin::User
- ::Admin.send :remove_const, :User
-
- Object.const_set(:User, Class.new(Sample))
+ Object.const_set(:User, Class.new(SampleTwo))
begin
with_default_wrapper_options do
@request.env['CONTENT_TYPE'] = 'application/json'
post :parse, { 'username' => 'sikachu', 'title' => 'Developer' }
- assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'user' => { 'username' => 'sikachu' }})
+ assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'user' => { 'title' => 'Developer' }})
end
ensure
Object.send :remove_const, :User
- ::Admin.const_set(:User, admin_user_constant)
end
end
@@ -241,6 +244,6 @@ class NamespacedParamsWrapperTest < ActionController::TestCase
end
def assert_parameters(expected)
- assert_equal expected, Admin::UsersController.last_parameters
+ assert_equal expected, Admin::Users::UsersController.last_parameters
end
-end
+end \ No newline at end of file
diff --git a/actionpack/test/controller/request_forgery_protection_test.rb b/actionpack/test/controller/request_forgery_protection_test.rb
index 31f4bf3a76..dea80ed887 100644
--- a/actionpack/test/controller/request_forgery_protection_test.rb
+++ b/actionpack/test/controller/request_forgery_protection_test.rb
@@ -81,22 +81,25 @@ module RequestForgeryProtectionTests
@token = "cf50faa3fe97702ca1ae"
ActiveSupport::SecureRandom.stubs(:base64).returns(@token)
- ActionController::Base.request_forgery_protection_token = :authenticity_token
+ ActionController::Base.request_forgery_protection_token = :custom_authenticity_token
end
+ def teardown
+ ActionController::Base.request_forgery_protection_token = nil
+ end
def test_should_render_form_with_token_tag
assert_not_blocked do
get :index
end
- assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token
+ assert_select 'form>div>input[name=?][value=?]', 'custom_authenticity_token', @token
end
def test_should_render_button_to_with_token_tag
assert_not_blocked do
get :show_button
end
- assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token
+ assert_select 'form>div>input[name=?][value=?]', 'custom_authenticity_token', @token
end
def test_should_allow_get
@@ -128,15 +131,15 @@ module RequestForgeryProtectionTests
end
def test_should_allow_post_with_token
- assert_not_blocked { post :index, :authenticity_token => @token }
+ assert_not_blocked { post :index, :custom_authenticity_token => @token }
end
def test_should_allow_put_with_token
- assert_not_blocked { put :index, :authenticity_token => @token }
+ assert_not_blocked { put :index, :custom_authenticity_token => @token }
end
def test_should_allow_delete_with_token
- assert_not_blocked { delete :index, :authenticity_token => @token }
+ assert_not_blocked { delete :index, :custom_authenticity_token => @token }
end
def test_should_allow_post_with_token_in_header
@@ -172,10 +175,18 @@ end
class RequestForgeryProtectionControllerTest < ActionController::TestCase
include RequestForgeryProtectionTests
+ setup do
+ ActionController::Base.request_forgery_protection_token = :custom_authenticity_token
+ end
+
+ teardown do
+ ActionController::Base.request_forgery_protection_token = nil
+ end
+
test 'should emit a csrf-param meta tag and a csrf-token meta tag' do
ActiveSupport::SecureRandom.stubs(:base64).returns(@token + '<=?')
get :meta
- assert_select 'meta[name=?][content=?]', 'csrf-param', 'authenticity_token'
+ assert_select 'meta[name=?][content=?]', 'csrf-param', 'custom_authenticity_token'
assert_select 'meta[name=?][content=?]', 'csrf-token', 'cf50faa3fe97702ca1ae&lt;=?'
end
end
diff --git a/activemodel/CHANGELOG b/activemodel/CHANGELOG
index c26924cf09..be4de2e53c 100644
--- a/activemodel/CHANGELOG
+++ b/activemodel/CHANGELOG
@@ -18,7 +18,36 @@
* Add support for selectively enabling/disabling observers [Myron Marston]
-*Rails 3.0.2 (unreleased)*
+*Rails 3.0.7 (April 18, 2011)*
+
+*No changes.
+
+
+*Rails 3.0.6 (April 5, 2011)
+
+* Fix when database column name has some symbolic characters (e.g. Oracle CASE# VARCHAR2(20)) #5818 #6850 [Robert Pankowecki, Santiago Pastorino]
+
+* Fix length validation for fixnums #6556 [Andriy Tyurnikov]
+
+* Fix i18n key collision with namespaced models #6448 [yves.senn]
+
+
+*Rails 3.0.5 (February 26, 2011)*
+
+* No changes.
+
+
+*Rails 3.0.4 (February 8, 2011)*
+
+* No changes.
+
+
+*Rails 3.0.3 (November 16, 2010)*
+
+* No changes.
+
+
+*Rails 3.0.2 (November 15, 2010)*
* No changes
diff --git a/activemodel/lib/active_model/serializers/xml.rb b/activemodel/lib/active_model/serializers/xml.rb
index d4295e6afe..19639b1363 100644
--- a/activemodel/lib/active_model/serializers/xml.rb
+++ b/activemodel/lib/active_model/serializers/xml.rb
@@ -33,6 +33,7 @@ module ActiveModel
protected
def compute_type
+ return if value.nil?
type = ActiveSupport::XmlMini::TYPE_NAMES[value.class.name]
type ||= :string if value.respond_to?(:to_str)
type ||= :yaml
diff --git a/activemodel/test/cases/serializers/xml_serialization_test.rb b/activemodel/test/cases/serializers/xml_serialization_test.rb
index b6a2f88667..8f5c196850 100644
--- a/activemodel/test/cases/serializers/xml_serialization_test.rb
+++ b/activemodel/test/cases/serializers/xml_serialization_test.rb
@@ -92,6 +92,10 @@ class XmlSerializationTest < ActiveModel::TestCase
test "should serialize string" do
assert_match %r{<name>aaron stack</name>}, @contact.to_xml
end
+
+ test "should serialize nil" do
+ assert_match %r{<pseudonyms nil=\"true\"></pseudonyms>}, @contact.to_xml(:methods => :pseudonyms)
+ end
test "should serialize integer" do
assert_match %r{<age type="integer">25</age>}, @contact.to_xml
diff --git a/activemodel/test/cases/validations/conditional_validation_test.rb b/activemodel/test/cases/validations/conditional_validation_test.rb
index 3cb95b4a00..e06b04af19 100644
--- a/activemodel/test/cases/validations/conditional_validation_test.rb
+++ b/activemodel/test/cases/validations/conditional_validation_test.rb
@@ -11,7 +11,7 @@ class ConditionalValidationTest < ActiveModel::TestCase
def test_if_validation_using_method_true
# When the method returns true
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :if => :condition_is_true )
+ Topic.validates_length_of( :title, :maximum => 5, :too_long => "hoo %{count}", :if => :condition_is_true )
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
assert t.invalid?
assert t.errors[:title].any?
@@ -20,7 +20,7 @@ class ConditionalValidationTest < ActiveModel::TestCase
def test_unless_validation_using_method_true
# When the method returns true
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :unless => :condition_is_true )
+ Topic.validates_length_of( :title, :maximum => 5, :too_long => "hoo %{count}", :unless => :condition_is_true )
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
assert t.valid?
assert t.errors[:title].empty?
@@ -28,7 +28,7 @@ class ConditionalValidationTest < ActiveModel::TestCase
def test_if_validation_using_method_false
# When the method returns false
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :if => :condition_is_true_but_its_not )
+ Topic.validates_length_of( :title, :maximum => 5, :too_long => "hoo %{count}", :if => :condition_is_true_but_its_not )
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
assert t.valid?
assert t.errors[:title].empty?
@@ -36,7 +36,7 @@ class ConditionalValidationTest < ActiveModel::TestCase
def test_unless_validation_using_method_false
# When the method returns false
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :unless => :condition_is_true_but_its_not )
+ Topic.validates_length_of( :title, :maximum => 5, :too_long => "hoo %{count}", :unless => :condition_is_true_but_its_not )
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
assert t.invalid?
assert t.errors[:title].any?
@@ -45,7 +45,7 @@ class ConditionalValidationTest < ActiveModel::TestCase
def test_if_validation_using_string_true
# When the evaluated string returns true
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :if => "a = 1; a == 1" )
+ Topic.validates_length_of( :title, :maximum => 5, :too_long => "hoo %{count}", :if => "a = 1; a == 1" )
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
assert t.invalid?
assert t.errors[:title].any?
@@ -54,7 +54,7 @@ class ConditionalValidationTest < ActiveModel::TestCase
def test_unless_validation_using_string_true
# When the evaluated string returns true
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :unless => "a = 1; a == 1" )
+ Topic.validates_length_of( :title, :maximum => 5, :too_long => "hoo %{count}", :unless => "a = 1; a == 1" )
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
assert t.valid?
assert t.errors[:title].empty?
@@ -62,7 +62,7 @@ class ConditionalValidationTest < ActiveModel::TestCase
def test_if_validation_using_string_false
# When the evaluated string returns false
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :if => "false")
+ Topic.validates_length_of( :title, :maximum => 5, :too_long => "hoo %{count}", :if => "false")
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
assert t.valid?
assert t.errors[:title].empty?
@@ -70,7 +70,7 @@ class ConditionalValidationTest < ActiveModel::TestCase
def test_unless_validation_using_string_false
# When the evaluated string returns false
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :unless => "false")
+ Topic.validates_length_of( :title, :maximum => 5, :too_long => "hoo %{count}", :unless => "false")
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
assert t.invalid?
assert t.errors[:title].any?
@@ -79,7 +79,7 @@ class ConditionalValidationTest < ActiveModel::TestCase
def test_if_validation_using_block_true
# When the block returns true
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}",
+ Topic.validates_length_of( :title, :maximum => 5, :too_long => "hoo %{count}",
:if => Proc.new { |r| r.content.size > 4 } )
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
assert t.invalid?
@@ -89,7 +89,7 @@ class ConditionalValidationTest < ActiveModel::TestCase
def test_unless_validation_using_block_true
# When the block returns true
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}",
+ Topic.validates_length_of( :title, :maximum => 5, :too_long => "hoo %{count}",
:unless => Proc.new { |r| r.content.size > 4 } )
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
assert t.valid?
@@ -98,7 +98,7 @@ class ConditionalValidationTest < ActiveModel::TestCase
def test_if_validation_using_block_false
# When the block returns false
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}",
+ Topic.validates_length_of( :title, :maximum => 5, :too_long => "hoo %{count}",
:if => Proc.new { |r| r.title != "uhohuhoh"} )
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
assert t.valid?
@@ -107,7 +107,7 @@ class ConditionalValidationTest < ActiveModel::TestCase
def test_unless_validation_using_block_false
# When the block returns false
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}",
+ Topic.validates_length_of( :title, :maximum => 5, :too_long => "hoo %{count}",
:unless => Proc.new { |r| r.title != "uhohuhoh"} )
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
assert t.invalid?
diff --git a/activemodel/test/cases/validations/format_validation_test.rb b/activemodel/test/cases/validations/format_validation_test.rb
index 73647efea5..2ce714fef0 100644
--- a/activemodel/test/cases/validations/format_validation_test.rb
+++ b/activemodel/test/cases/validations/format_validation_test.rb
@@ -27,7 +27,7 @@ class PresenceValidationTest < ActiveModel::TestCase
end
def test_validate_format_with_allow_blank
- Topic.validates_format_of(:title, :with => /^Validation\smacros \w+!$/, :allow_blank=>true)
+ Topic.validates_format_of(:title, :with => /^Validation\smacros \w+!$/, :allow_blank => true)
assert Topic.new("title" => "Shouldn't be valid").invalid?
assert Topic.new("title" => "").valid?
assert Topic.new("title" => nil).valid?
diff --git a/activemodel/test/cases/validations/inclusion_validation_test.rb b/activemodel/test/cases/validations/inclusion_validation_test.rb
index 92c473de0e..413da92de4 100644
--- a/activemodel/test/cases/validations/inclusion_validation_test.rb
+++ b/activemodel/test/cases/validations/inclusion_validation_test.rb
@@ -42,7 +42,7 @@ class InclusionValidationTest < ActiveModel::TestCase
end
def test_validates_inclusion_of_with_allow_nil
- Topic.validates_inclusion_of( :title, :in => %w( a b c d e f g ), :allow_nil=>true )
+ Topic.validates_inclusion_of( :title, :in => %w( a b c d e f g ), :allow_nil => true )
assert Topic.new("title" => "a!", "content" => "abc").invalid?
assert Topic.new("title" => "", "content" => "abc").invalid?
diff --git a/activemodel/test/cases/validations/length_validation_test.rb b/activemodel/test/cases/validations/length_validation_test.rb
index f02514639b..44048a9c1d 100644
--- a/activemodel/test/cases/validations/length_validation_test.rb
+++ b/activemodel/test/cases/validations/length_validation_test.rb
@@ -11,7 +11,7 @@ class LengthValidationTest < ActiveModel::TestCase
end
def test_validates_length_of_with_allow_nil
- Topic.validates_length_of( :title, :is => 5, :allow_nil=>true )
+ Topic.validates_length_of( :title, :is => 5, :allow_nil => true )
assert Topic.new("title" => "ab").invalid?
assert Topic.new("title" => "").invalid?
@@ -20,7 +20,7 @@ class LengthValidationTest < ActiveModel::TestCase
end
def test_validates_length_of_with_allow_blank
- Topic.validates_length_of( :title, :is => 5, :allow_blank=>true )
+ Topic.validates_length_of( :title, :is => 5, :allow_blank => true )
assert Topic.new("title" => "ab").invalid?
assert Topic.new("title" => "").valid?
@@ -176,16 +176,16 @@ class LengthValidationTest < ActiveModel::TestCase
end
def test_validates_length_of_nasty_params
- assert_raise(ArgumentError) { Topic.validates_length_of(:title, :is=>-6) }
- assert_raise(ArgumentError) { Topic.validates_length_of(:title, :within=>6) }
- assert_raise(ArgumentError) { Topic.validates_length_of(:title, :minimum=>"a") }
- assert_raise(ArgumentError) { Topic.validates_length_of(:title, :maximum=>"a") }
- assert_raise(ArgumentError) { Topic.validates_length_of(:title, :within=>"a") }
- assert_raise(ArgumentError) { Topic.validates_length_of(:title, :is=>"a") }
+ assert_raise(ArgumentError) { Topic.validates_length_of(:title, :is => -6) }
+ assert_raise(ArgumentError) { Topic.validates_length_of(:title, :within => 6) }
+ assert_raise(ArgumentError) { Topic.validates_length_of(:title, :minimum => "a") }
+ assert_raise(ArgumentError) { Topic.validates_length_of(:title, :maximum => "a") }
+ assert_raise(ArgumentError) { Topic.validates_length_of(:title, :within => "a") }
+ assert_raise(ArgumentError) { Topic.validates_length_of(:title, :is => "a") }
end
def test_validates_length_of_custom_errors_for_minimum_with_message
- Topic.validates_length_of( :title, :minimum=>5, :message=>"boo %{count}" )
+ Topic.validates_length_of( :title, :minimum => 5, :message => "boo %{count}" )
t = Topic.new("title" => "uhoh", "content" => "whatever")
assert t.invalid?
assert t.errors[:title].any?
@@ -193,7 +193,7 @@ class LengthValidationTest < ActiveModel::TestCase
end
def test_validates_length_of_custom_errors_for_minimum_with_too_short
- Topic.validates_length_of( :title, :minimum=>5, :too_short=>"hoo %{count}" )
+ Topic.validates_length_of( :title, :minimum => 5, :too_short => "hoo %{count}" )
t = Topic.new("title" => "uhoh", "content" => "whatever")
assert t.invalid?
assert t.errors[:title].any?
@@ -201,7 +201,7 @@ class LengthValidationTest < ActiveModel::TestCase
end
def test_validates_length_of_custom_errors_for_maximum_with_message
- Topic.validates_length_of( :title, :maximum=>5, :message=>"boo %{count}" )
+ Topic.validates_length_of( :title, :maximum => 5, :message => "boo %{count}" )
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
assert t.invalid?
assert t.errors[:title].any?
@@ -222,7 +222,7 @@ class LengthValidationTest < ActiveModel::TestCase
end
def test_validates_length_of_custom_errors_for_maximum_with_too_long
- Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}" )
+ Topic.validates_length_of( :title, :maximum => 5, :too_long => "hoo %{count}" )
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
assert t.invalid?
assert t.errors[:title].any?
@@ -244,7 +244,7 @@ class LengthValidationTest < ActiveModel::TestCase
end
def test_validates_length_of_custom_errors_for_is_with_message
- Topic.validates_length_of( :title, :is=>5, :message=>"boo %{count}" )
+ Topic.validates_length_of( :title, :is => 5, :message => "boo %{count}" )
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
assert t.invalid?
assert t.errors[:title].any?
@@ -252,7 +252,7 @@ class LengthValidationTest < ActiveModel::TestCase
end
def test_validates_length_of_custom_errors_for_is_with_wrong_length
- Topic.validates_length_of( :title, :is=>5, :wrong_length=>"hoo %{count}" )
+ Topic.validates_length_of( :title, :is => 5, :wrong_length => "hoo %{count}" )
t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
assert t.invalid?
assert t.errors[:title].any?
@@ -331,7 +331,7 @@ class LengthValidationTest < ActiveModel::TestCase
end
def test_validates_length_of_with_block
- Topic.validates_length_of :content, :minimum => 5, :too_short=>"Your essay must be at least %{count} words.",
+ Topic.validates_length_of :content, :minimum => 5, :too_short => "Your essay must be at least %{count} words.",
:tokenizer => lambda {|str| str.scan(/\w+/) }
t = Topic.new(:content => "this content should be long enough")
assert t.valid?
diff --git a/activemodel/test/models/contact.rb b/activemodel/test/models/contact.rb
index f4f3078473..7bfc542afb 100644
--- a/activemodel/test/models/contact.rb
+++ b/activemodel/test/models/contact.rb
@@ -16,6 +16,10 @@ class Contact
options.each { |name, value| send("#{name}=", value) }
end
+ def pseudonyms
+ nil
+ end
+
def persisted?
id
end
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index a03751a6c1..4dc652c08e 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*Rails 3.1.0 (unreleased)*
+* CSV Fixtures are deprecated and support will be removed in Rails 3.2.0
+
* AR#new, AR#create and AR#update_attributes all accept a second hash as option that allows you
to specify which role to consider when assigning attributes. This is built on top of ActiveModel's
new mass assignment capabilities:
@@ -290,6 +292,84 @@ IrreversibleMigration exception will be raised when going down.
[Aaron Patterson]
+*Rails 3.0.7 (April 18, 2011)*
+
+* Destroying records via nested attributes works independent of reject_if LH #6006 [Durran Jordan]
+
+* Delegate any? and many? to Model.scoped for consistency [Andrew White]
+
+* Quote the ORDER BY clause in batched finds - fixes #6620 [Andrew White]
+
+* Change exists? so records are not instantiated - fixes #6127. This prevents after_find
+ and after_initialize callbacks being triggered when checking for record existence.
+ [Andrew White]
+
+* Fix performance bug with attribute accessors which only occurred on Ruby 1.8.7, and ensure we
+ cache type-casted values when the column returned from the db contains non-standard chars.
+ [Jon Leighton]
+
+* Fix a performance regression introduced here 86acbf1cc050c8fa8c74a10c735e467fb6fd7df8
+ related to read_attribute method [Stian Grytøyr]
+
+
+*Rails 3.0.6 (April 5, 2011)*
+
+* Un-deprecate reorder method [Sebastian Martinez]
+
+* Extensions are applied when calling +except+ or +only+ on relations.
+ Thanks to Iain Hecker.
+
+* Schemas set in set_table_name are respected by the mysql adapter. LH #5322
+
+* Fixed a bug when empty? was called on a grouped Relation that wasn't loaded.
+ LH #5829
+
+* Reapply extensions when using except and only. Thanks Iain Hecker.
+
+* Binary data is escaped when being inserted to SQLite3 Databases. Thanks
+ Naruse!
+
+
+*Rails 3.0.5 (February 26, 2011)*
+
+* Model.where(:column => 1).where(:column => 2) will always produce an AND
+query.
+
+ [Aaron Patterson]
+
+* Deprecated support for interpolated association conditions in the form of :conditions => 'foo = #{bar}'.
+
+ Instead, you should use a proc, like so:
+
+ Before:
+
+ has_many :things, :conditions => 'foo = #{bar}'
+
+ After:
+
+ has_many :things, :conditions => proc { "foo = #{bar}" }
+
+ Inside the proc, 'self' is the object which is the owner of the association, unless you are
+ eager loading the association, in which case 'self' is the class which the association is within.
+
+ You can have any "normal" conditions inside the proc, so the following will work too:
+
+ has_many :things, :conditions => proc { ["foo = ?", bar] }
+
+ Previously :insert_sql and :delete_sql on has_and_belongs_to_many association allowed you to call
+ 'record' to get the record being inserted or deleted. This is now passed as an argument to
+ the proc.
+
+ [Jon Leighton]
+
+
+*Rails 3.0.4 (February 8, 2011)*
+
+* Added deprecation warning for has_and_belongs_to_many associations where the join table has
+ additional attributes other than the keys. Access to these attributes is removed in 3.1.
+ Please use has_many :through instead. [Jon Leighton]
+
+
*Rails 3.0.3 (November 16, 2010)*
* Support find by class like this: Post.where(:name => Post)
@@ -326,10 +406,12 @@ IrreversibleMigration exception will be raised when going down.
[Aaron Patterson]
+
*Rails 3.0.1 (October 15, 2010)*
* Introduce a fix for CVE-2010-3993
+
*Rails 3.0.0 (August 29, 2010)*
* Changed update_attribute to not run callbacks and update the record directly in the database [Neeraj Singh]
diff --git a/activerecord/lib/active_record/associations/builder/singular_association.rb b/activerecord/lib/active_record/associations/builder/singular_association.rb
index 06a414b874..62d48d3a2c 100644
--- a/activerecord/lib/active_record/associations/builder/singular_association.rb
+++ b/activerecord/lib/active_record/associations/builder/singular_association.rb
@@ -13,6 +13,19 @@ module ActiveRecord::Associations::Builder
private
+ def define_readers
+ super
+ name = self.name
+
+ model.redefine_method("#{name}_loaded?") do
+ ActiveSupport::Deprecation.warn(
+ "Calling obj.#{name}_loaded? is deprecated. Please use " \
+ "obj.association(:#{name}).loaded? instead."
+ )
+ association(name).loaded?
+ end
+ end
+
def define_constructors
name = self.name
diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb
index 85a4f47b7d..deb2b9af32 100644
--- a/activerecord/lib/active_record/associations/collection_association.rb
+++ b/activerecord/lib/active_record/associations/collection_association.rb
@@ -4,7 +4,7 @@ module ActiveRecord
module Associations
# = Active Record Association Collection
#
- # AssociationCollection is an abstract class that provides common stuff to
+ # CollectionAssociation is an abstract class that provides common stuff to
# ease the implementation of association proxies that represent
# collections. See the class hierarchy in AssociationProxy.
#
@@ -99,7 +99,6 @@ module ActiveRecord
else
add_to_target(build_record(attributes, options)) do |record|
yield(record) if block_given?
- set_owner_attributes(record)
end
end
end
@@ -423,7 +422,10 @@ module ActiveRecord
end
def build_record(attributes, options)
- reflection.build_association(scoped.scope_for_create.merge(attributes || {}), options)
+ record = reflection.build_association
+ record.assign_attributes(scoped.scope_for_create, :without_protection => true)
+ record.assign_attributes(attributes, options)
+ record
end
def delete_or_destroy(records, method)
diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb
index 7134dc85c8..2f3a6e71f1 100644
--- a/activerecord/lib/active_record/associations/has_one_association.rb
+++ b/activerecord/lib/active_record/associations/has_one_association.rb
@@ -10,7 +10,7 @@ module ActiveRecord
reflection.klass.transaction do
if target && target != record
- remove_target!(options[:dependent])
+ remove_target!(options[:dependent]) unless target.destroyed?
end
if record
diff --git a/activerecord/lib/active_record/associations/through_association.rb b/activerecord/lib/active_record/associations/through_association.rb
index e6ab628719..53c5c3cedf 100644
--- a/activerecord/lib/active_record/associations/through_association.rb
+++ b/activerecord/lib/active_record/associations/through_association.rb
@@ -14,7 +14,10 @@ module ActiveRecord
def target_scope
scope = super
chain[1..-1].each do |reflection|
- scope = scope.merge(reflection.klass.scoped)
+ scope = scope.merge(
+ reflection.klass.scoped.with_default_scope.
+ except(:select, :create_with)
+ )
end
scope
end
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index d07f9365b3..e1bf2ccc8a 100644
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -895,7 +895,7 @@ module ActiveRecord #:nodoc:
# not use the default_scope:
#
# Post.unscoped {
- # limit(10) # Fires "SELECT * FROM posts LIMIT 10"
+ # Post.limit(10) # Fires "SELECT * FROM posts LIMIT 10"
# }
#
# It is recommended to use block form of unscoped because chaining unscoped with <tt>scope</tt>
@@ -1652,11 +1652,10 @@ MSG
return unless new_attributes.is_a?(Hash)
- guard_protected_attributes ||= true
- if guard_protected_attributes
- assign_attributes(new_attributes)
- else
+ if guard_protected_attributes == false
assign_attributes(new_attributes, :without_protection => true)
+ else
+ assign_attributes(new_attributes)
end
end
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index 0e3ed7aac7..4aa6389a04 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -13,6 +13,7 @@ require 'active_support/core_ext/array/wrap'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/logger'
require 'active_support/ordered_hash'
+require 'active_support/core_ext/module/deprecation'
if defined? ActiveRecord
class FixtureClassNotFound < ActiveRecord::ActiveRecordError #:nodoc:
@@ -28,11 +29,9 @@ class FixturesFileNotFound < StandardError; end
#
# = Fixture formats
#
-# Fixtures come in 3 flavors:
+# Fixtures come in 1 flavor:
#
# 1. YAML fixtures
-# 2. CSV fixtures
-# 3. Single-file fixtures
#
# == YAML fixtures
#
@@ -74,56 +73,6 @@ class FixturesFileNotFound < StandardError; end
# parent_id: 1
# title: Child
#
-# == CSV fixtures
-#
-# Fixtures can also be kept in the Comma Separated Value (CSV) format. Akin to YAML fixtures, CSV fixtures are stored
-# in a single file, but instead end with the <tt>.csv</tt> file extension
-# (Rails example: <tt><your-rails-app>/test/fixtures/web_sites.csv</tt>).
-#
-# The format of this type of fixture file is much more compact than the others, but also a little harder to read by us
-# humans. The first line of the CSV file is a comma-separated list of field names. The rest of the
-# file is then comprised
-# of the actual data (1 per line). Here's an example:
-#
-# id, name, url
-# 1, Ruby On Rails, http://www.rubyonrails.org
-# 2, Google, http://www.google.com
-#
-# Should you have a piece of data with a comma character in it, you can place double quotes around that value. If you
-# need to use a double quote character, you must escape it with another double quote.
-#
-# Another unique attribute of the CSV fixture is that it has *no* fixture name like the other two formats. Instead, the
-# fixture names are automatically generated by deriving the class name of the fixture file and adding an incrementing
-# number to the end. In our example, the 1st fixture would be called "web_site_1" and the 2nd one would be called
-# "web_site_2".
-#
-# Most databases and spreadsheets support exporting to CSV format, so this is a great format for you to choose if you
-# have existing data somewhere already.
-#
-# == Single-file fixtures
-#
-# This type of fixture was the original format for Active Record that has since been deprecated in
-# favor of the YAML and CSV formats.
-# Fixtures for this format are created by placing text files in a sub-directory (with the name of the model)
-# to the directory appointed by <tt>ActiveSupport::TestCase.fixture_path=(path)</tt> (this is automatically
-# configured for Rails, so you can just put your files in <tt><your-rails-app>/test/fixtures/<your-model-name>/</tt> --
-# like <tt><your-rails-app>/test/fixtures/web_sites/</tt> for the WebSite model).
-#
-# Each text file placed in this directory represents a "record". Usually these types of fixtures are named without
-# extensions, but if you are on a Windows machine, you might consider adding <tt>.txt</tt> as the extension.
-# Here's what the above example might look like:
-#
-# web_sites/google
-# web_sites/yahoo.txt
-# web_sites/ruby-on-rails
-#
-# The file format of a standard fixture is simple. Each line is a property (or column in db speak) and has the syntax
-# of "name => value". Here's an example of the ruby-on-rails fixture above:
-#
-# id => 1
-# name => Ruby on Rails
-# url => http://www.rubyonrails.org
-#
# = Using fixtures in testcases
#
# Since fixtures are a testing construct, we use them in our unit and functional tests. There are two ways to use the
@@ -176,7 +125,7 @@ class FixturesFileNotFound < StandardError; end
# = Dynamic fixtures with ERB
#
# Some times you don't care about the content of the fixtures as much as you care about the volume. In these cases, you can
-# mix ERB in with your YAML or CSV fixtures to create a bunch of fixtures for load testing, like:
+# mix ERB in with your YAML fixtures to create a bunch of fixtures for load testing, like:
#
# <% for i in 1..1000 %>
# fix_<%= i %>:
@@ -752,6 +701,7 @@ module ActiveRecord
fixtures["#{@class_name.to_s.underscore}_#{i+=1}"] = ActiveRecord::Fixture.new(data, model_class)
end
end
+ deprecate :read_csv_fixture_files
def yaml_file_path
"#{@fixture_path}.yml"
diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb
index a8a52867ce..0fcae92d51 100644
--- a/activerecord/lib/active_record/relation/calculations.rb
+++ b/activerecord/lib/active_record/relation/calculations.rb
@@ -146,7 +146,7 @@ module ActiveRecord
if options.except(:distinct).present?
apply_finder_options(options.except(:distinct)).calculate(operation, column_name, :distinct => options[:distinct])
else
- if eager_loading? || includes_values.present?
+ if eager_loading? || (includes_values.present? && references_eager_loaded_tables?)
construct_relation_for_association_calculations.calculate(operation, column_name, options)
else
perform_calculation(operation, column_name, options)
@@ -161,21 +161,20 @@ module ActiveRecord
def perform_calculation(operation, column_name, options = {})
operation = operation.to_s.downcase
- distinct = nil
+ distinct = options[:distinct]
if operation == "count"
column_name ||= (select_for_count || :all)
unless arel.ast.grep(Arel::Nodes::OuterJoin).empty?
distinct = true
- column_name = primary_key if column_name == :all
end
+ column_name = primary_key if column_name == :all && distinct
+
distinct = nil if column_name =~ /\s*DISTINCT\s+/i
end
- distinct = options[:distinct] || distinct
-
if @group_values.any?
execute_grouped_calculation(operation, column_name, distinct)
else
diff --git a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb
index 39e8a7960a..49d8722aff 100644
--- a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb
+++ b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb
@@ -51,7 +51,9 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase
categories = Category.joins(:categorizations).includes([{:posts=>:comments}, :authors])
assert_nothing_raised do
- assert_equal 3, categories.count
+ assert_equal 4, categories.count
+ assert_equal 4, categories.all.count
+ assert_equal 3, categories.count(:distinct => true)
assert_equal 3, categories.all.uniq.size # Must uniq since instantiating with inner joins will get dupes
end
end
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index dc2481456b..b149f5912f 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -79,20 +79,48 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal 'defaulty', bulb.name
end
- def test_create_from_association_set_owner_attributes_by_passing_protection
- Bulb.attr_protected :car_id
+ def test_association_keys_bypass_attribute_protection
car = Car.create(:name => 'honda')
bulb = car.bulbs.new
assert_equal car.id, bulb.car_id
+ bulb = car.bulbs.new :car_id => car.id + 1
+ assert_equal car.id, bulb.car_id
+
bulb = car.bulbs.build
assert_equal car.id, bulb.car_id
+ bulb = car.bulbs.build :car_id => car.id + 1
+ assert_equal car.id, bulb.car_id
+
bulb = car.bulbs.create
assert_equal car.id, bulb.car_id
- ensure
- Bulb.attr_protected :id
+
+ bulb = car.bulbs.create :car_id => car.id + 1
+ assert_equal car.id, bulb.car_id
+ end
+
+ def test_association_conditions_bypass_attribute_protection
+ car = Car.create(:name => 'honda')
+
+ bulb = car.frickinawesome_bulbs.new
+ assert_equal true, bulb.frickinawesome?
+
+ bulb = car.frickinawesome_bulbs.new(:frickinawesome => false)
+ assert_equal true, bulb.frickinawesome?
+
+ bulb = car.frickinawesome_bulbs.build
+ assert_equal true, bulb.frickinawesome?
+
+ bulb = car.frickinawesome_bulbs.build(:frickinawesome => false)
+ assert_equal true, bulb.frickinawesome?
+
+ bulb = car.frickinawesome_bulbs.create
+ assert_equal true, bulb.frickinawesome?
+
+ bulb = car.frickinawesome_bulbs.create(:frickinawesome => false)
+ assert_equal true, bulb.frickinawesome?
end
# When creating objects on the association, we must not do it within a scope (even though it
diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb
index f3c96ccbe6..c2a82b8c60 100644
--- a/activerecord/test/cases/associations/has_one_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_associations_test.rb
@@ -95,6 +95,15 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
assert_nil Account.find(old_account_id).firm_id
end
+ def test_natural_assignment_to_nil_after_destroy
+ firm = companies(:rails_core)
+ old_account_id = firm.account.id
+ firm.account.destroy
+ firm.account = nil
+ assert_nil companies(:rails_core).account
+ assert_raise(ActiveRecord::RecordNotFound) { Account.find(old_account_id) }
+ end
+
def test_association_change_calls_delete
companies(:first_firm).deletable_account = Account.new(:credit_limit => 5)
assert_equal [], Account.destroyed_account_ids[companies(:first_firm).id]
@@ -359,4 +368,13 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
assert_equal pirate.id, ships(:black_pearl).reload.pirate_id
assert_nil new_ship.pirate_id
end
+
+ def test_deprecated_association_loaded
+ firm = companies(:first_firm)
+ firm.association(:account).stubs(:loaded?).returns(stub)
+
+ assert_deprecated do
+ assert_equal firm.association(:account).loaded?, firm.account_loaded?
+ end
+ end
end
diff --git a/activerecord/test/cases/associations/has_one_through_associations_test.rb b/activerecord/test/cases/associations/has_one_through_associations_test.rb
index 968025ade8..2503349c08 100644
--- a/activerecord/test/cases/associations/has_one_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_through_associations_test.rb
@@ -310,4 +310,8 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase
assert_equal dashboard, minivan.dashboard
assert_equal dashboard, minivan.speedometer.dashboard
end
+
+ def test_has_one_through_with_custom_select_on_join_model_default_scope
+ assert_equal clubs(:boring_club), members(:groucho).selected_club
+ end
end
diff --git a/activerecord/test/cases/associations/inner_join_association_test.rb b/activerecord/test/cases/associations/inner_join_association_test.rb
index 124693f7c9..55d9a328a7 100644
--- a/activerecord/test/cases/associations/inner_join_association_test.rb
+++ b/activerecord/test/cases/associations/inner_join_association_test.rb
@@ -2,6 +2,7 @@ require "cases/helper"
require 'models/post'
require 'models/comment'
require 'models/author'
+require 'models/essay'
require 'models/category'
require 'models/categorization'
require 'models/person'
diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb
index 04f628a398..49d82ba2df 100644
--- a/activerecord/test/cases/associations_test.rb
+++ b/activerecord/test/cases/associations_test.rb
@@ -85,7 +85,7 @@ class AssociationsTest < ActiveRecord::TestCase
def test_should_construct_new_finder_sql_after_create
person = Person.new :first_name => 'clark'
- assert_equal [], person.readers.find(:all)
+ assert_equal [], person.readers.all
person.save!
reader = Reader.create! :person => person, :post => Post.new(:title => "foo", :body => "bar")
assert person.readers.find(reader.id)
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 1775ba9999..9bc04ed29c 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -45,6 +45,10 @@ class ReadonlyTitlePost < Post
attr_readonly :title
end
+class ProtectedTitlePost < Post
+ attr_protected :title
+end
+
class Weird < ActiveRecord::Base; end
class Boolean < ActiveRecord::Base; end
@@ -105,7 +109,7 @@ class BasicsTest < ActiveRecord::TestCase
def test_select_symbol
topic_ids = Topic.select(:id).map(&:id).sort
- assert_equal Topic.find(:all).map(&:id).sort, topic_ids
+ assert_equal Topic.all.map(&:id).sort, topic_ids
end
def test_table_exists
@@ -491,8 +495,9 @@ class BasicsTest < ActiveRecord::TestCase
def test_attributes_guard_protected_attributes_is_deprecated
attributes = { "title" => "An amazing title" }
- topic = Topic.new
- assert_deprecated { topic.send(:attributes=, attributes, false) }
+ post = ProtectedTitlePost.new
+ assert_deprecated { post.send(:attributes=, attributes, false) }
+ assert_equal "An amazing title", post.title
end
def test_multiparameter_attributes_on_date
diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb
index 654c4c9010..56f6d795b6 100644
--- a/activerecord/test/cases/calculations_test.rb
+++ b/activerecord/test/cases/calculations_test.rb
@@ -319,6 +319,17 @@ class CalculationsTest < ActiveRecord::TestCase
assert_equal 4, Account.count(:distinct => true, :include => :firm, :select => :credit_limit)
end
+ def test_should_not_perform_joined_include_by_default
+ assert_equal Account.count, Account.includes(:firm).count
+ queries = assert_sql { Account.includes(:firm).count }
+ assert_no_match(/join/i, queries.last)
+ end
+
+ def test_should_perform_joined_include_when_referencing_included_tables
+ joined_count = Account.includes(:firm).where(:companies => {:name => '37signals'}).count
+ assert_equal 1, joined_count
+ end
+
def test_should_count_scoped_select
Account.update_all("credit_limit = NULL")
assert_equal 0, Account.scoped(:select => "credit_limit").count
diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb
index 2bf192e2c6..b0bd9c5763 100644
--- a/activerecord/test/cases/fixtures_test.rb
+++ b/activerecord/test/cases/fixtures_test.rb
@@ -175,7 +175,9 @@ class FixturesTest < ActiveRecord::TestCase
end
def test_empty_csv_fixtures
- assert_not_nil ActiveRecord::Fixtures.new( Account.connection, "accounts", 'Account', FIXTURES_ROOT + "/naked/csv/accounts")
+ assert_deprecated do
+ assert_not_nil ActiveRecord::Fixtures.new( Account.connection, "accounts", 'Account', FIXTURES_ROOT + "/naked/csv/accounts")
+ end
end
def test_omap_fixtures
diff --git a/activerecord/test/cases/method_scoping_test.rb b/activerecord/test/cases/method_scoping_test.rb
index 7f0f007a70..a0cb5dbdc5 100644
--- a/activerecord/test/cases/method_scoping_test.rb
+++ b/activerecord/test/cases/method_scoping_test.rb
@@ -68,7 +68,7 @@ class MethodScopingTest < ActiveRecord::TestCase
def test_scoped_find_all
Developer.send(:with_scope, :find => { :conditions => "name = 'David'" }) do
- assert_equal [developers(:david)], Developer.find(:all)
+ assert_equal [developers(:david)], Developer.all
end
end
@@ -235,23 +235,23 @@ class MethodScopingTest < ActiveRecord::TestCase
def test_immutable_scope
options = { :conditions => "name = 'David'" }
Developer.send(:with_scope, :find => options) do
- assert_equal %w(David), Developer.find(:all).map { |d| d.name }
+ assert_equal %w(David), Developer.all.map(&:name)
options[:conditions] = "name != 'David'"
- assert_equal %w(David), Developer.find(:all).map { |d| d.name }
+ assert_equal %w(David), Developer.all.map(&:name)
end
scope = { :find => { :conditions => "name = 'David'" }}
Developer.send(:with_scope, scope) do
- assert_equal %w(David), Developer.find(:all).map { |d| d.name }
+ assert_equal %w(David), Developer.all.map(&:name)
scope[:find][:conditions] = "name != 'David'"
- assert_equal %w(David), Developer.find(:all).map { |d| d.name }
+ assert_equal %w(David), Developer.all.map(&:name)
end
end
def test_scoped_with_duck_typing
scoping = Struct.new(:current_scope).new(:find => { :conditions => ["name = ?", 'David'] })
Developer.send(:with_scope, scoping) do
- assert_equal %w(David), Developer.find(:all).map { |d| d.name }
+ assert_equal %w(David), Developer.all.map(&:name)
end
end
@@ -432,7 +432,7 @@ class NestedScopingTest < ActiveRecord::TestCase
def test_merged_scoped_find_combines_and_sanitizes_conditions
Developer.send(:with_scope, :find => { :conditions => ["name = ?", 'David'] }) do
Developer.send(:with_scope, :find => { :conditions => ['salary > ?', 9000] }) do
- assert_equal %w(David), Developer.find(:all).map { |d| d.name }
+ assert_equal %w(David), Developer.all.map(&:name)
end
end
end
@@ -487,9 +487,9 @@ class NestedScopingTest < ActiveRecord::TestCase
options2 = { :conditions => "name = 'David'" }
Developer.send(:with_scope, :find => options1) do
Developer.send(:with_exclusive_scope, :find => options2) do
- assert_equal %w(David), Developer.find(:all).map { |d| d.name }
+ assert_equal %w(David), Developer.all.map(&:name)
options1[:conditions] = options2[:conditions] = nil
- assert_equal %w(David), Developer.find(:all).map { |d| d.name }
+ assert_equal %w(David), Developer.all.map(&:name)
end
end
end
@@ -499,9 +499,9 @@ class NestedScopingTest < ActiveRecord::TestCase
options2 = { :conditions => "salary > 10000" }
Developer.send(:with_scope, :find => options1) do
Developer.send(:with_scope, :find => options2) do
- assert_equal %w(Jamis), Developer.find(:all).map { |d| d.name }
+ assert_equal %w(Jamis), Developer.all.map(&:name)
options1[:conditions] = options2[:conditions] = nil
- assert_equal %w(Jamis), Developer.find(:all).map { |d| d.name }
+ assert_equal %w(Jamis), Developer.all.map(&:name)
end
end
end
diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb
index 8fd1fc2577..34188e4915 100644
--- a/activerecord/test/cases/named_scope_test.rb
+++ b/activerecord/test/cases/named_scope_test.rb
@@ -462,7 +462,7 @@ class NamedScopeTest < ActiveRecord::TestCase
[:destroy_all, :reset, :delete_all].each do |method|
before = post.comments.containing_the_letter_e
post.association(:comments).send(method)
- assert before.object_id != post.comments.containing_the_letter_e.object_id, "AssociationCollection##{method} should reset the named scopes cache"
+ assert before.object_id != post.comments.containing_the_letter_e.object_id, "CollectionAssociation##{method} should reset the named scopes cache"
end
end
diff --git a/activerecord/test/cases/xml_serialization_test.rb b/activerecord/test/cases/xml_serialization_test.rb
index a6074b23e7..756c8a32eb 100644
--- a/activerecord/test/cases/xml_serialization_test.rb
+++ b/activerecord/test/cases/xml_serialization_test.rb
@@ -143,10 +143,7 @@ class NilXmlSerializationTest < ActiveRecord::TestCase
end
def test_should_serialize_yaml
- assert %r{<preferences(.*)></preferences>}.match(@xml)
- attributes = $1
- assert_match %r{type="yaml"}, attributes
- assert_match %r{nil="true"}, attributes
+ assert_match %r{<preferences nil=\"true\"></preferences>}, @xml
end
end
diff --git a/activerecord/test/fixtures/all/people.csv b/activerecord/test/fixtures/all/people.yml
index e69de29bb2..e69de29bb2 100644
--- a/activerecord/test/fixtures/all/people.csv
+++ b/activerecord/test/fixtures/all/people.yml
diff --git a/activerecord/test/fixtures/memberships.yml b/activerecord/test/fixtures/memberships.yml
index 60eb641054..a5d52bd438 100644
--- a/activerecord/test/fixtures/memberships.yml
+++ b/activerecord/test/fixtures/memberships.yml
@@ -25,3 +25,10 @@ blarpy_winkup_crazy_club:
member_id: 3
favourite: false
type: CurrentMembership
+
+selected_membership_of_boring_club:
+ joined_on: <%= 3.weeks.ago.to_s(:db) %>
+ club: boring_club
+ member_id: 1
+ favourite: false
+ type: SelectedMembership
diff --git a/activerecord/test/models/bulb.rb b/activerecord/test/models/bulb.rb
index c68d008c26..643dcefed3 100644
--- a/activerecord/test/models/bulb.rb
+++ b/activerecord/test/models/bulb.rb
@@ -2,6 +2,8 @@ class Bulb < ActiveRecord::Base
default_scope where(:name => 'defaulty')
belongs_to :car
+ attr_protected :car_id, :frickinawesome
+
attr_reader :scope_after_initialize
after_initialize :record_scope_after_initialize
diff --git a/activerecord/test/models/car.rb b/activerecord/test/models/car.rb
index b036f0f5c9..de1864345a 100644
--- a/activerecord/test/models/car.rb
+++ b/activerecord/test/models/car.rb
@@ -2,6 +2,8 @@ class Car < ActiveRecord::Base
has_many :bulbs
has_many :foo_bulbs, :class_name => "Bulb", :conditions => { :name => 'foo' }
+ has_many :frickinawesome_bulbs, :class_name => "Bulb", :conditions => { :frickinawesome => true }
+
has_many :tyres
has_many :engines
has_many :wheels, :as => :wheelable
diff --git a/activerecord/test/models/member.rb b/activerecord/test/models/member.rb
index 991e0e051f..11a0f4ff63 100644
--- a/activerecord/test/models/member.rb
+++ b/activerecord/test/models/member.rb
@@ -1,8 +1,10 @@
class Member < ActiveRecord::Base
has_one :current_membership
+ has_one :selected_membership
has_one :membership
has_many :fellow_members, :through => :club, :source => :members
has_one :club, :through => :current_membership
+ has_one :selected_club, :through => :selected_membership, :source => :club
has_one :favourite_club, :through => :membership, :conditions => ["memberships.favourite = ?", true], :source => :club
has_one :hairy_club, :through => :membership, :conditions => {:clubs => {:name => "Moustache and Eyebrow Fancier Club"}}, :source => :club
has_one :sponsor, :as => :sponsorable
diff --git a/activerecord/test/models/membership.rb b/activerecord/test/models/membership.rb
index 905f948c37..bcbb7e42c5 100644
--- a/activerecord/test/models/membership.rb
+++ b/activerecord/test/models/membership.rb
@@ -7,3 +7,9 @@ class CurrentMembership < Membership
belongs_to :member
belongs_to :club
end
+
+class SelectedMembership < Membership
+ def self.default_scope
+ select("'1' as foo")
+ end
+end
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index c20304c0e2..c8a98f121d 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -89,6 +89,7 @@ ActiveRecord::Schema.define do
create_table :bulbs, :force => true do |t|
t.integer :car_id
t.string :name
+ t.boolean :frickinawesome
end
create_table "CamelCase", :force => true do |t|
diff --git a/activeresource/CHANGELOG b/activeresource/CHANGELOG
index 386bafd7de..a4e79f3d77 100644
--- a/activeresource/CHANGELOG
+++ b/activeresource/CHANGELOG
@@ -2,14 +2,42 @@
* No changes
-*Rails 3.0.2 (unreleased)*
+
+*Rails 3.0.7 (April 18, 2011)*
+
+*No changes.
+
+
+*Rails 3.0.6 (April 5, 2011)
+
+* No changes.
+
+
+*Rails 3.0.5 (February 26, 2011)*
+
+* No changes.
+
+
+*Rails 3.0.4 (February 8, 2011)*
+
+* No changes.
+
+
+*Rails 3.0.3 (November 16, 2010)*
+
+* No changes.
+
+
+*Rails 3.0.2 (November 15, 2010)*
* No changes
+
*Rails 3.0.1 (October 15, 2010)*
* No Changes, just a version bump.
+
*Rails 3.0.0 (August 29, 2010)*
* JSON: set Base.include_root_in_json = true to include a root value in the JSON: {"post": {"title": ...}}. Mirrors the Active Record option. [Santiago Pastorino]
diff --git a/activeresource/test/cases/format_test.rb b/activeresource/test/cases/format_test.rb
index fc1a7b8c6f..f8d33f99fa 100644
--- a/activeresource/test/cases/format_test.rb
+++ b/activeresource/test/cases/format_test.rb
@@ -86,7 +86,7 @@ class FormatTest < Test::Unit::TestCase
def test_serialization_of_nested_resource
address = { :street => '12345 Street' }
- person = { :name=> 'Rus', :address => address}
+ person = { :name => 'Rus', :address => address}
[:json, :xml].each do |format|
encoded_person = ActiveResource::Formats[format].encode(person)
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG
index ca8973f001..b5b0af8e85 100644
--- a/activesupport/CHANGELOG
+++ b/activesupport/CHANGELOG
@@ -19,14 +19,44 @@ advantage of the new ClassCache.
* Added before_remove_const callback to ActiveSupport::Dependencies.remove_unloadable_constants! [Andrew White]
+* 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.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)
+
+* No changes.
+
+
+*Rails 3.0.5 (February 26, 2011)*
+
+* No changes.
+
+
+*Rails 3.0.4 (February 8, 2011)*
+
+* No changes.
+
+
+*Rails 3.0.3 (November 16, 2010)*
+
+* No changes.
+
+
*Rails 3.0.2 (November 15, 2010)*
* Added before_remove_const callback to ActiveSupport::Dependencies.remove_unloadable_constants! [Andrew White]
+
*Rails 3.0.1 (October 15, 2010)*
* No Changes, just a version bump.
+
*Rails 3.0.0 (August 29, 2010)*
* Implemented String#strip_heredoc. [fxn]
diff --git a/activesupport/README.rdoc b/activesupport/README.rdoc
index 13ca4b3bf1..8bb15e849a 100644
--- a/activesupport/README.rdoc
+++ b/activesupport/README.rdoc
@@ -30,4 +30,4 @@ API documentation is at
Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here:
-* https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets
+* https://github.com/rails/rails/issues
diff --git a/activesupport/lib/active_support/buffered_logger.rb b/activesupport/lib/active_support/buffered_logger.rb
index 88b50fc506..a14f008be5 100644
--- a/activesupport/lib/active_support/buffered_logger.rb
+++ b/activesupport/lib/active_support/buffered_logger.rb
@@ -49,10 +49,12 @@ module ActiveSupport
@log = log
elsif File.exist?(log)
@log = open(log, (File::WRONLY | File::APPEND))
+ @log.binmode
@log.sync = true
else
FileUtils.mkdir_p(File.dirname(log))
@log = open(log, (File::WRONLY | File::APPEND | File::CREAT))
+ @log.binmode
@log.sync = true
end
end
diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb
index 1fafc36ee8..d22fe14b33 100644
--- a/activesupport/lib/active_support/json/encoding.rb
+++ b/activesupport/lib/active_support/json/encoding.rb
@@ -2,6 +2,7 @@ require 'active_support/core_ext/object/to_json'
require 'active_support/core_ext/module/delegation'
require 'active_support/deprecation'
require 'active_support/json/variable'
+require 'active_support/ordered_hash'
require 'bigdecimal'
require 'active_support/core_ext/big_decimal/conversions' # for #to_s
diff --git a/activesupport/test/buffered_logger_test.rb b/activesupport/test/buffered_logger_test.rb
index 8d1b1c02c6..21049d685b 100644
--- a/activesupport/test/buffered_logger_test.rb
+++ b/activesupport/test/buffered_logger_test.rb
@@ -2,6 +2,7 @@ require 'abstract_unit'
require 'multibyte_test_helpers'
require 'stringio'
require 'fileutils'
+require 'tempfile'
require 'active_support/buffered_logger'
class BufferedLoggerTest < Test::Unit::TestCase
@@ -16,6 +17,44 @@ class BufferedLoggerTest < Test::Unit::TestCase
@logger = Logger.new(@output)
end
+ def test_write_binary_data_to_existing_file
+ t = Tempfile.new ['development', 'log']
+ t.binmode
+ t.write 'hi mom!'
+ t.close
+
+ logger = Logger.new t.path
+ logger.level = Logger::DEBUG
+
+ str = "\x80"
+ if str.respond_to?(:force_encoding)
+ str.force_encoding("ASCII-8BIT")
+ end
+
+ logger.add Logger::DEBUG, str
+ logger.flush
+ ensure
+ logger.close
+ t.close true
+ end
+
+ def test_write_binary_data_create_file
+ fname = File.join Dir.tmpdir, 'lol', 'rofl.log'
+ logger = Logger.new fname
+ logger.level = Logger::DEBUG
+
+ str = "\x80"
+ if str.respond_to?(:force_encoding)
+ str.force_encoding("ASCII-8BIT")
+ end
+
+ logger.add Logger::DEBUG, str
+ logger.flush
+ ensure
+ logger.close
+ File.unlink fname
+ end
+
def test_should_log_debugging_message_when_debugging
@logger.level = Logger::DEBUG
@logger.add(Logger::DEBUG, @message)
diff --git a/activesupport/test/ordered_hash_test.rb b/activesupport/test/ordered_hash_test.rb
index bf99a701a6..f3dcd7b068 100644
--- a/activesupport/test/ordered_hash_test.rb
+++ b/activesupport/test/ordered_hash_test.rb
@@ -1,6 +1,7 @@
require 'abstract_unit'
require 'active_support/json'
require 'active_support/core_ext/object/to_json'
+require 'active_support/core_ext/hash/indifferent_access'
class OrderedHashTest < Test::Unit::TestCase
def setup
diff --git a/railties/CHANGELOG b/railties/CHANGELOG
index 21666103de..e058b624b5 100644
--- a/railties/CHANGELOG
+++ b/railties/CHANGELOG
@@ -74,10 +74,42 @@ by the prototype-rails gem. [fxn]
* Include all helpers from plugins and shared engines in application [Piotr Sarnacki]
+
+*Rails 3.0.7 (April 18, 2011)*
+
+*No changes.
+
+
+*Rails 3.0.6 (April 5, 2011)
+
+* No changes.
+
+
+*Rails 3.0.5 (February 26, 2011)*
+
+* No changes.
+
+
+*Rails 3.0.4 (February 8, 2011)*
+
+* No changes.
+
+
+*Rails 3.0.3 (November 16, 2010)*
+
+* No changes.
+
+
+*Rails 3.0.2 (November 15, 2010)*
+
+* No changes.
+
+
*Rails 3.0.1 (October 15, 2010)*
* No Changes, just a version bump.
+
*Rails 3.0.0 (August 29, 2010)*
* Application generation: --skip-testunit and --skip-activerecord become --skip-test-unit and --skip-active-record respectively. [fxn]
diff --git a/railties/guides/source/testing.textile b/railties/guides/source/testing.textile
index efa2bbdca6..38b8d0d521 100644
--- a/railties/guides/source/testing.textile
+++ b/railties/guides/source/testing.textile
@@ -54,7 +54,7 @@ For good tests, you'll need to give some thought to setting up test data. In Rai
h5. What are Fixtures?
-_Fixtures_ is a fancy word for sample data. Fixtures allow you to populate your testing database with predefined data before your tests run. Fixtures are database independent and assume one of two formats: *YAML* or *CSV*. In this guide, we will use *YAML*, which is the preferred format.
+_Fixtures_ is a fancy word for sample data. Fixtures allow you to populate your testing database with predefined data before your tests run. Fixtures are database independent and assume a single format: *YAML*.
You'll find fixtures under your +test/fixtures+ directory. When you run +rails generate model+ to create a new model, fixture stubs will be automatically created and placed in this directory.
@@ -81,7 +81,7 @@ Each fixture is given a name followed by an indented list of colon-separated key
h5. ERB'in It Up
-ERB allows you to embed ruby code within templates. Both the YAML and CSV fixture formats are pre-processed with ERB when you load fixtures. This allows you to use Ruby to help you generate some sample data.
+ERB allows you to embed ruby code within templates. YAML fixture format is pre-processed with ERB when you load fixtures. This allows you to use Ruby to help you generate some sample data.
<erb>
<% earth_size = 20 %>
diff --git a/railties/lib/rails/commands/runner.rb b/railties/lib/rails/commands/runner.rb
index ddd08a32ee..f8b00e7249 100644
--- a/railties/lib/rails/commands/runner.rb
+++ b/railties/lib/rails/commands/runner.rb
@@ -25,7 +25,7 @@ ARGV.clone.options do |opts|
opts.separator "-------------------------------------------------------------"
opts.separator "#!/usr/bin/env #{File.expand_path($0)} runner"
opts.separator ""
- opts.separator "Product.find(:all).each { |p| p.price *= 2 ; p.save! }"
+ opts.separator "Product.all.each { |p| p.price *= 2 ; p.save! }"
opts.separator "-------------------------------------------------------------"
end
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index 2015a944f0..6a125685d0 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -523,6 +523,7 @@ module Rails
initializer :append_assets_path do |app|
app.config.assets.paths.unshift *paths["vendor/assets"].existent
+ app.config.assets.paths.unshift *paths["lib/assets"].existent
app.config.assets.paths.unshift *paths["app/assets"].existent
end
diff --git a/railties/lib/rails/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb
index 241db4b0a9..f424492bb4 100644
--- a/railties/lib/rails/engine/configuration.rb
+++ b/railties/lib/rails/engine/configuration.rb
@@ -47,6 +47,7 @@ module Rails
paths.add "app/mailers", :eager_load => true
paths.add "app/views"
paths.add "lib", :load_path => true
+ paths.add "lib/assets", :glob => "*"
paths.add "lib/tasks", :glob => "**/*.rake"
paths.add "config"
paths.add "config/environments", :glob => "#{Rails.env}.rb"
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile
index a69efdf29d..3af28bb416 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile
@@ -9,7 +9,7 @@ source 'http://rubygems.org'
<%= "gem 'json'\n" if RUBY_VERSION < "1.9.2" -%>
gem 'sass'
gem 'coffee-script'
-gem 'uglifier'
+gem 'uglifier', :git => 'git://github.com/lautis/uglifier.git'
<%= gem_for_javascript %>
@@ -22,4 +22,4 @@ gem 'uglifier'
# To use debugger
# <%= gem_for_ruby_debugger %>
-<%= gem_for_turn -%> \ No newline at end of file
+<%= gem_for_turn -%>
diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt
index 612c614f2e..19294b3478 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt
+++ b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt
@@ -1,5 +1,8 @@
-// FIXME: Tell people that this is a manifest file, real code should go into discrete files
-// FIXME: Tell people how Sprockets and CoffeeScript works
+// This is a manifest file that'll be compiled into including all the files listed below.
+// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
+// be included in the compiled file accessible from http://example.com/assets/application.js
+// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
+// the compiled file.
//
<% unless options[:skip_javascript] -%>
//= require <%= options[:javascript] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css b/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css
index f4b082ccc0..fc25b5723f 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css
+++ b/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css
@@ -1,5 +1,7 @@
/*
- * FIXME: Introduce SCSS & Sprockets
+ * This is a manifest file that'll automatically include all the stylesheets available in this directory
+ * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
+ * the top of the compiled file, but it's generally better to create a new file per style scope.
*= require_self
*= require_tree .
*/ \ No newline at end of file
diff --git a/railties/lib/rails/generators/rails/app/templates/gitignore b/railties/lib/rails/generators/rails/app/templates/gitignore
index f0fa30c536..923b697662 100644
--- a/railties/lib/rails/generators/rails/app/templates/gitignore
+++ b/railties/lib/rails/generators/rails/app/templates/gitignore
@@ -2,3 +2,4 @@
db/*.sqlite3
log/*.log
tmp/
+.sass-cache/
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 6193e72625..43876c0a72 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -225,8 +225,6 @@ module ApplicationTests
make_basic_app
class ::OmgController < ActionController::Base
- protect_from_forgery
-
def index
render :inline => "<%= csrf_meta_tags %>"
end
@@ -236,6 +234,21 @@ module ApplicationTests
assert last_response.body =~ /csrf\-param/
end
+ test "request forgery token param can be changed" do
+ make_basic_app do
+ app.config.action_controller.request_forgery_protection_token = '_xsrf_token_here'
+ end
+
+ class ::OmgController < ActionController::Base
+ def index
+ render :inline => "<%= csrf_meta_tags %>"
+ end
+ end
+
+ get "/"
+ assert last_response.body =~ /_xsrf_token_here/
+ end
+
test "config.action_controller.perform_caching = true" do
make_basic_app do |app|
app.config.action_controller.perform_caching = true
diff --git a/railties/test/application/initializers/frameworks_test.rb b/railties/test/application/initializers/frameworks_test.rb
index 19311a7fa0..196d121c14 100644
--- a/railties/test/application/initializers/frameworks_test.rb
+++ b/railties/test/application/initializers/frameworks_test.rb
@@ -166,7 +166,7 @@ module ApplicationTests
require "#{app_path}/config/environment"
- expects = [ActiveRecord::IdentityMap::Middleware, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActiveRecord::SessionStore]
+ expects = [ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActiveRecord::SessionStore]
middleware = Rails.application.config.middleware.map { |m| m.klass }
assert_equal expects, middleware & expects
end
diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb
index fd6dc46271..8bfde00af5 100644
--- a/railties/test/application/middleware_test.rb
+++ b/railties/test/application/middleware_test.rb
@@ -30,7 +30,6 @@ module ApplicationTests
"Rack::Sendfile",
"ActionDispatch::Reloader",
"ActionDispatch::Callbacks",
- "ActiveRecord::IdentityMap::Middleware",
"ActiveRecord::ConnectionAdapters::ConnectionManagement",
"ActiveRecord::QueryCache",
"ActionDispatch::Cookies",
@@ -121,6 +120,7 @@ module ApplicationTests
end
test "identity map is inserted" do
+ add_to_config "config.active_record.identity_map = true"
boot!
assert middleware.include?("ActiveRecord::IdentityMap::Middleware")
end