diff options
-rw-r--r-- | Gemfile | 1 | ||||
-rw-r--r-- | activejob/activejob.gemspec | 2 | ||||
-rw-r--r-- | activejob/lib/active_job/arguments.rb | 2 | ||||
-rw-r--r-- | activejob/test/cases/parameters_test.rb | 16 | ||||
-rw-r--r-- | activejob/test/helper.rb | 2 | ||||
-rw-r--r-- | activerecord/CHANGELOG.md | 7 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation/query_methods.rb | 4 | ||||
-rw-r--r-- | activerecord/test/cases/adapters/postgresql/view_test.rb | 88 | ||||
-rw-r--r-- | activerecord/test/cases/relation/mutation_test.rb | 4 | ||||
-rw-r--r-- | activerecord/test/cases/relations_test.rb | 5 | ||||
-rw-r--r-- | activerecord/test/cases/view_test.rb | 36 | ||||
-rw-r--r-- | activesupport/CHANGELOG.md | 5 | ||||
-rw-r--r-- | activesupport/lib/active_support/message_verifier.rb | 1 | ||||
-rw-r--r-- | activesupport/test/message_verifier_test.rb | 7 | ||||
-rw-r--r-- | guides/source/active_record_querying.md | 6 | ||||
-rw-r--r-- | guides/source/asset_pipeline.md | 4 | ||||
-rw-r--r-- | guides/source/maintenance_policy.md | 6 |
17 files changed, 118 insertions, 78 deletions
@@ -8,7 +8,6 @@ gemspec gem 'mocha', '~> 0.14', require: false gem 'rack-cache', '~> 1.2' -# TODO: Release this gem gem 'jquery-rails', '~> 4.0.0.beta2' gem 'coffee-rails', '~> 4.0.0' # TODO: Release this gem diff --git a/activejob/activejob.gemspec b/activejob/activejob.gemspec index 9944b2a1bd..a9be2a8f00 100644 --- a/activejob/activejob.gemspec +++ b/activejob/activejob.gemspec @@ -19,5 +19,5 @@ Gem::Specification.new do |s| s.require_path = 'lib' s.add_dependency 'activesupport', version - s.add_dependency 'globalid', '>= 0.2.3' + s.add_dependency 'globalid', '>= 0.3.0' end diff --git a/activejob/lib/active_job/arguments.rb b/activejob/lib/active_job/arguments.rb index 69a4ad928d..175a2f0956 100644 --- a/activejob/lib/active_job/arguments.rb +++ b/activejob/lib/active_job/arguments.rb @@ -38,7 +38,7 @@ module ActiveJob def serialize_argument(argument) case argument when GlobalID::Identification - argument.global_id.to_s + argument.to_global_id.to_s when *TYPE_WHITELIST argument when Array diff --git a/activejob/test/cases/parameters_test.rb b/activejob/test/cases/parameters_test.rb index 78853c51e1..92f835af5d 100644 --- a/activejob/test/cases/parameters_test.rb +++ b/activejob/test/cases/parameters_test.rb @@ -26,8 +26,8 @@ class ParameterSerializationTest < ActiveSupport::TestCase end test 'should dive deep into arrays or hashes' do - assert_equal [ { "a" => Person.find(5).gid.to_s }.with_indifferent_access ], ActiveJob::Arguments.serialize([ { a: Person.find(5) } ]) - assert_equal [ [ Person.find(5).gid.to_s ] ], ActiveJob::Arguments.serialize([ [ Person.find(5) ] ]) + assert_equal [ { "a" => Person.find(5).to_gid.to_s }.with_indifferent_access ], ActiveJob::Arguments.serialize([ { a: Person.find(5) } ]) + assert_equal [ [ Person.find(5).to_gid.to_s ] ], ActiveJob::Arguments.serialize([ [ Person.find(5) ] ]) end test 'should dive deep into arrays or hashes and raise exception on complex objects' do @@ -45,11 +45,11 @@ class ParameterSerializationTest < ActiveSupport::TestCase end test 'should serialize records with global id' do - assert_equal [ Person.find(5).gid.to_s ], ActiveJob::Arguments.serialize([ Person.find(5) ]) + assert_equal [ Person.find(5).to_gid.to_s ], ActiveJob::Arguments.serialize([ Person.find(5) ]) end test 'should serialize values and records together' do - assert_equal [ 3, Person.find(5).gid.to_s ], ActiveJob::Arguments.serialize([ 3, Person.find(5) ]) + assert_equal [ 3, Person.find(5).to_gid.to_s ], ActiveJob::Arguments.serialize([ 3, Person.find(5) ]) end end @@ -59,19 +59,19 @@ class ParameterDeserializationTest < ActiveSupport::TestCase end test 'should deserialize records with global id' do - assert_equal [ Person.find(5) ], ActiveJob::Arguments.deserialize([ Person.find(5).gid ]) + assert_equal [ Person.find(5) ], ActiveJob::Arguments.deserialize([ Person.find(5).to_gid ]) end test 'should serialize values and records together' do - assert_equal [ 3, Person.find(5) ], ActiveJob::Arguments.deserialize([ 3, Person.find(5).gid ]) + assert_equal [ 3, Person.find(5) ], ActiveJob::Arguments.deserialize([ 3, Person.find(5).to_gid ]) end test 'should dive deep when deserialising arrays' do - assert_equal [ [ 3, Person.find(5) ] ], ActiveJob::Arguments.deserialize([ [ 3, Person.find(5).gid ] ]) + assert_equal [ [ 3, Person.find(5) ] ], ActiveJob::Arguments.deserialize([ [ 3, Person.find(5).to_gid ] ]) end test 'should dive deep when deserialising hashes' do - assert_equal [ { "5" => Person.find(5) } ], ActiveJob::Arguments.deserialize([ { "5" => Person.find(5).gid } ]) + assert_equal [ { "5" => Person.find(5) } ], ActiveJob::Arguments.deserialize([ { "5" => Person.find(5).to_gid } ]) end end diff --git a/activejob/test/helper.rb b/activejob/test/helper.rb index 3386cef6f3..ce22833b11 100644 --- a/activejob/test/helper.rb +++ b/activejob/test/helper.rb @@ -27,4 +27,4 @@ end require 'active_support/testing/autorun' ActiveJob::Base.logger.level = Logger::DEBUG - +ActiveSupport::TestCase.test_order = :random diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 7d4869e113..13e8292954 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,10 @@ +* A `NullRelation` should represent nothing. This fixes a bug where + `Comment.where(post_id: Post.none)` returned a non-empty result. + + Closes #15176. + + *Matthew Draper*, *Yves Senn* + * Include default column limits in schema.rb. Allows defaults to be changed in the future without affecting old migrations that assumed old defaults. diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index e6a088d07e..bbddd28ccc 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -687,11 +687,11 @@ module ActiveRecord # end # def none - extending(NullRelation) + where("1=0").extending!(NullRelation) end def none! # :nodoc: - extending!(NullRelation) + where!("1=0").extending!(NullRelation) end # Sets readonly attributes for the returned relation. If value is diff --git a/activerecord/test/cases/adapters/postgresql/view_test.rb b/activerecord/test/cases/adapters/postgresql/view_test.rb index 47b7d38eda..8a8e1d3b17 100644 --- a/activerecord/test/cases/adapters/postgresql/view_test.rb +++ b/activerecord/test/cases/adapters/postgresql/view_test.rb @@ -1,67 +1,63 @@ require "cases/helper" +require "cases/view_test" -module ViewTestConcern - extend ActiveSupport::Concern +class UpdateableViewTest < ActiveRecord::TestCase + fixtures :books - included do - self.use_transactional_fixtures = false - mattr_accessor :view_type + class PrintedBook < ActiveRecord::Base + self.primary_key = "id" end - SCHEMA_NAME = 'test_schema' - TABLE_NAME = 'things' - COLUMNS = [ - 'id integer', - 'name character varying(50)', - 'email character varying(50)', - 'moment timestamp without time zone' - ] - - class ThingView < ActiveRecord::Base + setup do + @connection = ActiveRecord::Base.connection + @connection.execute <<-SQL + CREATE VIEW printed_books + AS SELECT id, name, status, format FROM books WHERE format = 'paperback' + SQL end - def setup - super - ThingView.table_name = "#{SCHEMA_NAME}.#{view_type}_things" - - @connection = ActiveRecord::Base.connection - @connection.execute "CREATE SCHEMA #{SCHEMA_NAME} CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})" - @connection.execute "CREATE #{view_type.humanize} #{ThingView.table_name} AS SELECT * FROM #{SCHEMA_NAME}.#{TABLE_NAME}" + teardown do + @connection.execute "DROP VIEW printed_books" if @connection.table_exists? "printed_books" end - def teardown - super - @connection.execute "DROP SCHEMA #{SCHEMA_NAME} CASCADE" + def test_update_record + book = PrintedBook.first + book.name = "AWDwR" + book.save! + book.reload + assert_equal "AWDwR", book.name end - def test_table_exists - name = ThingView.table_name - assert @connection.table_exists?(name), "'#{name}' table should exist" + def test_insert_record + PrintedBook.create! name: "Rails in Action", status: 0, format: "paperback" + + new_book = PrintedBook.last + assert_equal "Rails in Action", new_book.name end - def test_column_definitions - assert_nothing_raised do - assert_equal COLUMNS, columns(ThingView.table_name) + def test_update_record_to_fail_view_conditions + book = PrintedBook.first + book.format = "ebook" + book.save! + + assert_raises ActiveRecord::RecordNotFound do + book.reload end end +end - private - def columns(table_name) - @connection.send(:column_definitions, table_name).map do |name, type, default| - "#{name} #{type}" + (default ? " default #{default}" : '') - end - end +if ActiveRecord::Base.connection.supports_materialized_views? +class MaterializedViewTest < ActiveRecord::TestCase + include ViewBehavior -end + private + def create_view(name, query) + @connection.execute "CREATE MATERIALIZED VIEW #{name} AS #{query}" + end -class ViewTest < ActiveRecord::TestCase - include ViewTestConcern - self.view_type = 'view' -end + def drop_view(name) + @connection.execute "DROP MATERIALIZED VIEW #{name}" if @connection.table_exists? name -if ActiveRecord::Base.connection.supports_materialized_views? - class MaterializedViewTest < ActiveRecord::TestCase - include ViewTestConcern - self.view_type = 'materialized_view' end end +end diff --git a/activerecord/test/cases/relation/mutation_test.rb b/activerecord/test/cases/relation/mutation_test.rb index 1da5c36e1c..4c94c2fd0d 100644 --- a/activerecord/test/cases/relation/mutation_test.rb +++ b/activerecord/test/cases/relation/mutation_test.rb @@ -18,6 +18,10 @@ module ActiveRecord def attribute_alias?(name) false end + + def sanitize_sql(sql) + sql + end end def relation diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index 7163697a68..410b5ba5a3 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -420,6 +420,11 @@ class RelationTest < ActiveRecord::TestCase assert_equal nil, ac.engines.maximum(:id) end + def test_null_relation_in_where_condition + assert_operator Comment.count, :>, 0 # precondition, make sure there are comments. + assert_equal 0, Comment.where(post_id: Post.none).to_a.size + end + def test_joins_with_nil_argument assert_nothing_raised { DependentFirm.joins(nil).first } end diff --git a/activerecord/test/cases/view_test.rb b/activerecord/test/cases/view_test.rb index 357265aa05..3aed90ba36 100644 --- a/activerecord/test/cases/view_test.rb +++ b/activerecord/test/cases/view_test.rb @@ -1,24 +1,28 @@ require "cases/helper" require "models/book" -if ActiveRecord::Base.connection.supports_views? -class ViewWithPrimaryKeyTest < ActiveRecord::TestCase - fixtures :books +module ViewBehavior + extend ActiveSupport::Concern + + included do + fixtures :books + end class Ebook < ActiveRecord::Base self.primary_key = "id" end - setup do + def setup + super @connection = ActiveRecord::Base.connection - @connection.execute <<-SQL - CREATE VIEW ebooks - AS SELECT id, name, status FROM books WHERE format = 'ebook' + create_view "ebooks", <<-SQL + SELECT id, name, status FROM books WHERE format = 'ebook' SQL end - teardown do - @connection.execute "DROP VIEW ebooks" if @connection.table_exists? "ebooks" + def teardown + super + drop_view "ebooks" end def test_reading @@ -51,6 +55,20 @@ class ViewWithPrimaryKeyTest < ActiveRecord::TestCase end end +if ActiveRecord::Base.connection.supports_views? +class ViewWithPrimaryKeyTest < ActiveRecord::TestCase + include ViewBehavior + + private + def create_view(name, query) + @connection.execute "CREATE VIEW #{name} AS #{query}" + end + + def drop_view(name) + @connection.execute "DROP VIEW #{name}" if @connection.table_exists? name + end +end + class ViewWithoutPrimaryKeyTest < ActiveRecord::TestCase fixtures :books diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index 0e5a28e3fc..8b76fa97d1 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,3 +1,8 @@ +* `MessageVerifier.new` raises an appropriate exception if the secret is `nil`. + This prevents `MessageVerifier#generate` from raising a cryptic error later on. + + *Kostiantyn Kahanskyi* + * Introduced new configuration option `active_support.test_order` for specifying the order test cases are executed. This option currently defaults to `:sorted` but will be changed to `:random` in Rails 5.0. diff --git a/activesupport/lib/active_support/message_verifier.rb b/activesupport/lib/active_support/message_verifier.rb index 8e6e1dcfeb..6cb2884fb7 100644 --- a/activesupport/lib/active_support/message_verifier.rb +++ b/activesupport/lib/active_support/message_verifier.rb @@ -27,6 +27,7 @@ module ActiveSupport class InvalidSignature < StandardError; end def initialize(secret, options = {}) + raise ArgumentError, 'Secret should not be nil.' unless secret @secret = secret @digest = options[:digest] || 'SHA1' @serializer = options[:serializer] || Marshal diff --git a/activesupport/test/message_verifier_test.rb b/activesupport/test/message_verifier_test.rb index a5748d28ba..28035bc428 100644 --- a/activesupport/test/message_verifier_test.rb +++ b/activesupport/test/message_verifier_test.rb @@ -69,6 +69,13 @@ class MessageVerifierTest < ActiveSupport::TestCase "undefined class/module MessageVerifierTest::AutoloadClass"], exception.message end + def test_raise_error_when_secret_is_nil + exception = assert_raise(ArgumentError) do + ActiveSupport::MessageVerifier.new(nil) + end + assert_equal exception.message, 'Secret should not be nil.' + end + def assert_not_verified(message) assert_raise(ActiveSupport::MessageVerifier::InvalidSignature) do @verifier.verify(message) diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md index cb243c95f5..e1a465c64f 100644 --- a/guides/source/active_record_querying.md +++ b/guides/source/active_record_querying.md @@ -340,16 +340,14 @@ The `find_in_batches` method is similar to `find_each`, since both retrieve batc ```ruby # Give add_invoices an array of 1000 invoices at a time -Invoice.find_in_batches(include: :invoice_lines) do |invoices| +Invoice.find_in_batches do |invoices| export.add_invoices(invoices) end ``` -NOTE: The `:include` option allows you to name associations that should be loaded alongside with the models. - ##### Options for `find_in_batches` -The `find_in_batches` method accepts the same `:batch_size` and `:start` options as `find_each`, as well as most of the options allowed by the regular `find` method, except for `:order` and `:limit`, which are reserved for internal use by `find_in_batches`. +The `find_in_batches` method accepts the same `:batch_size` and `:start` options as `find_each`. Conditions ---------- diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md index 2a8940684f..c19c8e0bec 100644 --- a/guides/source/asset_pipeline.md +++ b/guides/source/asset_pipeline.md @@ -735,10 +735,10 @@ Rails.application.config.assets.precompile << Proc.new do |path| full_path = Rails.application.assets.resolve(path).to_path app_assets_path = Rails.root.join('app', 'assets').to_path if full_path.starts_with? app_assets_path - puts "including asset: " + full_path + logger.info "including asset: " + full_path true else - puts "excluding asset: " + full_path + logger.info "excluding asset: " + full_path false end else diff --git a/guides/source/maintenance_policy.md b/guides/source/maintenance_policy.md index 6f8584b3b7..7f084dd54c 100644 --- a/guides/source/maintenance_policy.md +++ b/guides/source/maintenance_policy.md @@ -39,7 +39,7 @@ Only the latest release series will receive bug fixes. When enough bugs are fixed and its deemed worthy to release a new gem, this is the branch it happens from. -**Currently included series:** `4.1.Z`, `4.0.Z`. +**Currently included series:** `4.2.Z`, `4.1.Z`. Security Issues --------------- @@ -54,7 +54,7 @@ be built from 1.2.2, and then added to the end of 1-2-stable. This means that security releases are easy to upgrade to if you're running the latest version of Rails. -**Currently included series:** `4.1.Z`, `4.0.Z`. +**Currently included series:** `4.2.Z`, `4.1.Z`. Severe Security Issues ---------------------- @@ -63,7 +63,7 @@ For severe security issues we will provide new versions as above, and also the last major release series will receive patches and new versions. The classification of the security issue is judged by the core team. -**Currently included series:** `4.1.Z`, `4.0.Z`, `3.2.Z`. +**Currently included series:** `4.2.Z`, `4.1.Z`, `3.2.Z`. Unsupported Release Series -------------------------- |