aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/action_view/path_set.rb6
-rw-r--r--actionpack/lib/action_view/renderer/abstract_renderer.rb15
-rw-r--r--actionpack/lib/action_view/renderer/partial_renderer.rb14
-rw-r--r--actionpack/lib/action_view/renderer/renderer.rb6
-rw-r--r--activerecord/CHANGELOG.md4
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb2
-rw-r--r--activerecord/lib/active_record/core.rb6
-rw-r--r--activerecord/lib/active_record/migration.rb17
-rw-r--r--activerecord/test/cases/adapters/postgresql/array_test.rb6
-rw-r--r--activerecord/test/cases/clone_test.rb7
-rw-r--r--activerecord/test/cases/migration_test.rb26
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt2
12 files changed, 102 insertions, 9 deletions
diff --git a/actionpack/lib/action_view/path_set.rb b/actionpack/lib/action_view/path_set.rb
index d9c76366f8..91ee2ea8f5 100644
--- a/actionpack/lib/action_view/path_set.rb
+++ b/actionpack/lib/action_view/path_set.rb
@@ -1,5 +1,11 @@
module ActionView #:nodoc:
# = Action View PathSet
+ #
+ # This class is used to store and access paths in Action View. A number of
+ # operations are defined so that you can search among the paths in this
+ # set and also perform operations on other +PathSet+ objects.
+ #
+ # A +LookupContext+ will use a +PathSet+ to store the paths in its context.
class PathSet #:nodoc:
include Enumerable
diff --git a/actionpack/lib/action_view/renderer/abstract_renderer.rb b/actionpack/lib/action_view/renderer/abstract_renderer.rb
index 6fb8cbb46c..73c19a0ae2 100644
--- a/actionpack/lib/action_view/renderer/abstract_renderer.rb
+++ b/actionpack/lib/action_view/renderer/abstract_renderer.rb
@@ -1,4 +1,19 @@
module ActionView
+ # This class defines the interface for a renderer. Each class that
+ # subclasses +AbstractRenderer+ is used by the base +Renderer+ class to
+ # render a specific type of object.
+ #
+ # The base +Renderer+ class uses its +render+ method to delegate to the
+ # renderers. These currently consist of
+ #
+ # PartialRenderer - Used for rendering partials
+ # TemplateRenderer - Used for rendering other types of templates
+ # StreamingTemplateRenderer - Used for streaming
+ #
+ # Whenever the +render+ method is called on the base +Renderer+ class, a new
+ # renderer object of the correct type is created, and the +render+ method on
+ # that new object is called in turn. This abstracts the setup and rendering
+ # into a separate classes for partials and templates.
class AbstractRenderer #:nodoc:
delegate :find_template, :template_exists?, :with_fallbacks, :with_layout_format, :formats, :to => :@lookup_context
diff --git a/actionpack/lib/action_view/renderer/partial_renderer.rb b/actionpack/lib/action_view/renderer/partial_renderer.rb
index 43a88b0623..821026268a 100644
--- a/actionpack/lib/action_view/renderer/partial_renderer.rb
+++ b/actionpack/lib/action_view/renderer/partial_renderer.rb
@@ -313,6 +313,13 @@ module ActionView
private
+ # Sets up instance variables needed for rendering a partial. This method
+ # finds the options and details and extracts them. The method also contains
+ # logic that handles the type of object passed in as the partial.
+ #
+ # If +options[:partial]+ is a string, then the +@path+ instance variable is
+ # set to that string. Otherwise, the +options[:partial]+ object must
+ # respond to +to_partial_path+ in order to setup the path.
def setup(context, options, block)
@view = context
partial = options[:partial]
@@ -413,6 +420,13 @@ module ActionView
end
end
+ # Obtains the path to where the object's partial is located. If the object
+ # responds to +to_partial_path+, then +to_partial_path+ will be called and
+ # will provide the path. If the object does not respond to +to_partial_path+,
+ # then an +ArgumentError+ is raised.
+ #
+ # If +prefix_partial_path_with_controller_namespace+ is true, then this
+ # method will prefix the partial paths with a namespace.
def partial_path(object = @object)
object = object.to_model if object.respond_to?(:to_model)
diff --git a/actionpack/lib/action_view/renderer/renderer.rb b/actionpack/lib/action_view/renderer/renderer.rb
index 30a0c4be70..964b18337e 100644
--- a/actionpack/lib/action_view/renderer/renderer.rb
+++ b/actionpack/lib/action_view/renderer/renderer.rb
@@ -2,6 +2,12 @@ module ActionView
# This is the main entry point for rendering. It basically delegates
# to other objects like TemplateRenderer and PartialRenderer which
# actually renders the template.
+ #
+ # The Renderer will parse the options from the +render+ or +render_body+
+ # method and render a partial or a template based on the options. The
+ # +TemplateRenderer+ and +PartialRenderer+ objects are wrappers which do all
+ # the setup and logic necessary to render a view and a new object is created
+ # each time +render+ is called.
class Renderer
attr_accessor :lookup_context
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 52300fd53f..278da322f2 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,5 +1,9 @@
## Rails 4.0.0 (unreleased) ##
+* Run `rake migrate:down` & `rake migrate:up` in transaction if database supports.
+
+ *Alexander Bondarev*
+
* `0x` prefix must be added when assigning hexadecimal string into `bit` column in PostgreSQL.
*kennyj*
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
index 6329733abc..40a3b82839 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
@@ -32,7 +32,7 @@ module ActiveRecord
when 'point' then super(PostgreSQLColumn.point_to_string(value))
else
if column.array
- "'#{PostgreSQLColumn.array_to_string(value, column, self)}'"
+ "'#{PostgreSQLColumn.array_to_string(value, column, self).gsub(/'/, "''")}'"
else
super
end
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index 733d4e1c67..9e45e6e474 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -307,9 +307,11 @@ module ActiveRecord
id.hash
end
- # Freeze the attributes hash such that associations are still accessible, even on destroyed records.
+ # Clone and freeze the attributes hash such that associations are still
+ # accessible, even on destroyed records, but cloned models will not be
+ # frozen.
def freeze
- @attributes.freeze
+ @attributes = @attributes.clone.freeze
self
end
diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb
index 451104106c..2d2ca4c8e8 100644
--- a/activerecord/lib/active_record/migration.rb
+++ b/activerecord/lib/active_record/migration.rb
@@ -867,11 +867,18 @@ module ActiveRecord
alias :current :current_migration
def run
- target = migrations.detect { |m| m.version == @target_version }
- raise UnknownMigrationVersionError.new(@target_version) if target.nil?
- unless (up? && migrated.include?(target.version.to_i)) || (down? && !migrated.include?(target.version.to_i))
- target.migrate(@direction)
- record_version_state_after_migrating(target.version)
+ migration = migrations.detect { |m| m.version == @target_version }
+ raise UnknownMigrationVersionError.new(@target_version) if migration.nil?
+ unless (up? && migrated.include?(migration.version.to_i)) || (down? && !migrated.include?(migration.version.to_i))
+ begin
+ ddl_transaction(migration) do
+ migration.migrate(@direction)
+ record_version_state_after_migrating(migration.version)
+ end
+ rescue => e
+ canceled_msg = use_transaction?(migration) ? ", this migration was canceled" : ""
+ raise StandardError, "An error has occurred#{canceled_msg}:\n\n#{e}", e.backtrace
+ end
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/array_test.rb b/activerecord/test/cases/adapters/postgresql/array_test.rb
index 8774bf626f..61a3a2ba0f 100644
--- a/activerecord/test/cases/adapters/postgresql/array_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/array_test.rb
@@ -81,6 +81,12 @@ class PostgresqlArrayTest < ActiveRecord::TestCase
assert_cycle(['1',nil,nil])
end
+ def test_insert_fixture
+ tag_values = ["val1", "val2", "val3_with_'_multiple_quote_'_chars"]
+ @connection.insert_fixture({"tags" => tag_values}, "pg_arrays" )
+ assert_equal(PgArray.last.tags, tag_values)
+ end
+
private
def assert_cycle array
# test creation
diff --git a/activerecord/test/cases/clone_test.rb b/activerecord/test/cases/clone_test.rb
index d91646efca..5e43082c33 100644
--- a/activerecord/test/cases/clone_test.rb
+++ b/activerecord/test/cases/clone_test.rb
@@ -29,5 +29,12 @@ module ActiveRecord
topic.author_name = 'Aaron'
assert_equal 'Aaron', cloned.author_name
end
+
+ def test_freezing_a_cloned_model_does_not_freeze_clone
+ cloned = Topic.new
+ clone = cloned.clone
+ cloned.freeze
+ assert_not clone.frozen?
+ end
end
end
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index f8afb7c591..193ffb26e3 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -258,6 +258,32 @@ class MigrationTest < ActiveRecord::TestCase
"On error, the Migrator should revert schema changes but it did not."
end
+ def test_migrator_one_up_with_exception_and_rollback_using_run
+ unless ActiveRecord::Base.connection.supports_ddl_transactions?
+ skip "not supported on #{ActiveRecord::Base.connection.class}"
+ end
+
+ assert_not Person.column_methods_hash.include?(:last_name)
+
+ migration = Class.new(ActiveRecord::Migration) {
+ def version; 100 end
+ def migrate(x)
+ add_column "people", "last_name", :string
+ raise 'Something broke'
+ end
+ }.new
+
+ migrator = ActiveRecord::Migrator.new(:up, [migration], 100)
+
+ e = assert_raise(StandardError) { migrator.run }
+
+ assert_equal "An error has occurred, this migration was canceled:\n\nSomething broke", e.message
+
+ Person.reset_column_information
+ assert_not Person.column_methods_hash.include?(:last_name),
+ "On error, the Migrator should revert schema changes but it did not."
+ end
+
def test_migration_without_transaction
unless ActiveRecord::Base.connection.supports_ddl_transactions?
skip "not supported on #{ActiveRecord::Base.connection.class}"
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
index 3c9c787948..7073d8db33 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
@@ -13,7 +13,7 @@
config.eager_load = false
# Configure static asset server for tests with Cache-Control for performance.
- config.serve_static_assets = true
+ config.serve_static_assets = true
config.static_cache_control = "public, max-age=3600"
# Show full error reports and disable caching.