aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG.md16
-rw-r--r--activerecord/examples/performance.rb2
-rw-r--r--activerecord/lib/active_record/associations.rb2
-rw-r--r--activerecord/lib/active_record/associations/collection_proxy.rb10
-rw-r--r--activerecord/lib/active_record/attribute_methods/primary_key.rb2
-rw-r--r--activerecord/lib/active_record/attribute_methods/read.rb4
-rw-r--r--activerecord/lib/active_record/base.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb57
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb10
-rw-r--r--activerecord/lib/active_record/connection_adapters/schema_cache.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb6
-rw-r--r--activerecord/lib/active_record/fixtures.rb11
-rw-r--r--activerecord/lib/active_record/migration.rb52
-rw-r--r--activerecord/lib/active_record/railtie.rb4
-rw-r--r--activerecord/lib/active_record/railties/databases.rake4
-rw-r--r--activerecord/lib/active_record/transactions.rb10
-rw-r--r--activerecord/test/cases/associations/extension_test.rb6
-rw-r--r--activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb6
-rw-r--r--activerecord/test/cases/fixtures_test.rb2
-rw-r--r--activerecord/test/cases/helper.rb11
-rw-r--r--activerecord/test/cases/log_subscriber_test.rb1
-rw-r--r--activerecord/test/cases/migration_test.rb128
-rw-r--r--activerecord/test/cases/session_store/session_test.rb1
-rw-r--r--activerecord/test/migrations/rename/1_we_need_things.rb11
-rw-r--r--activerecord/test/migrations/rename/2_rename_things.rb9
-rw-r--r--activerecord/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb9
-rw-r--r--activerecord/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb9
-rw-r--r--activerecord/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb12
-rw-r--r--activerecord/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb12
-rw-r--r--activerecord/test/models/post.rb6
32 files changed, 309 insertions, 122 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 888bc43ec9..cd8e50b33a 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,5 +1,17 @@
## Rails 3.2.0 (unreleased) ##
+* Added ability to run migrations only for given scope, which allows
+ to run migrations only from one engine (for example to revert changes
+ from engine that you want to remove).
+
+ Example:
+ rake db:migrate SCOPE=blog
+
+ *Piotr Sarnacki*
+
+* Migrations copied from engines are now scoped with engine's name,
+ for example 01_create_posts.blog.rb. *Piotr Sarnacki*
+
* Implements `AR::Base.silence_auto_explain`. This method allows the user to
selectively disable automatic EXPLAINs within a block. *fxn*
@@ -134,6 +146,10 @@
during :reject_if => :all_blank (fixes #2937)
*Aaron Christy*
+
+* Add ActiveSupport::Cache::NullStore for use in development and testing.
+
+ *Brian Durand*
## Rails 3.1.3 (unreleased) ##
diff --git a/activerecord/examples/performance.rb b/activerecord/examples/performance.rb
index 0f62e819ee..d29af85278 100644
--- a/activerecord/examples/performance.rb
+++ b/activerecord/examples/performance.rb
@@ -1,6 +1,6 @@
TIMES = (ENV['N'] || 10000).to_i
-require 'rubygems'
+require File.expand_path('../../../load_paths', __FILE__)
require "active_record"
conn = { :adapter => 'sqlite3', :database => ':memory:' }
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index a7600a07d8..0efa111d12 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -70,7 +70,7 @@ module ActiveRecord
end
end
- class HasManyThroughNestedAssociationsAreReadonly < ActiveRecordError #:nodoc
+ class HasManyThroughNestedAssociationsAreReadonly < ActiveRecordError #:nodoc:
def initialize(owner, reflection)
super("Cannot modify association '#{owner.class.name}##{reflection.name}' because it goes through more than one other association.")
end
diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb
index 80bc4990d2..eb320bc774 100644
--- a/activerecord/lib/active_record/associations/collection_proxy.rb
+++ b/activerecord/lib/active_record/associations/collection_proxy.rb
@@ -41,8 +41,7 @@ module ActiveRecord
delegate :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from,
:lock, :readonly, :having, :pluck, :to => :scoped
- delegate :target, :load_target, :loaded?, :scoped,
- :to => :@association
+ delegate :target, :load_target, :loaded?, :to => :@association
delegate :select, :find, :first, :last,
:build, :create, :create!,
@@ -62,6 +61,13 @@ module ActiveRecord
@association
end
+ def scoped
+ association = @association
+ association.scoped.extending do
+ define_method(:proxy_association) { association }
+ end
+ end
+
def respond_to?(name, include_private = false)
super ||
(load_target && target.respond_to?(name, include_private)) ||
diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb
index c756924186..746682393e 100644
--- a/activerecord/lib/active_record/attribute_methods/primary_key.rb
+++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb
@@ -72,7 +72,7 @@ module ActiveRecord
when :table_name_with_underscore
base_name.foreign_key
else
- if ActiveRecord::Base != self && connection.table_exists?(table_name)
+ if ActiveRecord::Base != self && connection.schema_cache.table_exists?(table_name)
connection.primary_key(table_name)
else
'id'
diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb
index 8942fab500..25c998e857 100644
--- a/activerecord/lib/active_record/attribute_methods/read.rb
+++ b/activerecord/lib/active_record/attribute_methods/read.rb
@@ -55,7 +55,7 @@ module ActiveRecord
internal = internal_attribute_access_code(attr_name, cast_code)
external = external_attribute_access_code(attr_name, cast_code)
- generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__
+ generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
def __temp__
#{internal}
end
@@ -63,7 +63,7 @@ module ActiveRecord
undef_method :__temp__
STR
- generated_attribute_methods.singleton_class.module_eval <<-STR, __FILE__, __LINE__
+ generated_attribute_methods.singleton_class.module_eval <<-STR, __FILE__, __LINE__ + 1
def __temp__(v, attributes, attributes_cache, attr_name)
#{external}
end
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 7ba585b8e0..ba75dc6d09 100644
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -762,7 +762,7 @@ module ActiveRecord #:nodoc:
# Indicates whether the table associated with this class exists
def table_exists?
- connection.table_exists?(table_name)
+ connection.schema_cache.table_exists?(table_name)
end
# Returns an array of column objects for the table associated with this class.
@@ -2222,8 +2222,6 @@ MSG
include AutosaveAssociation, NestedAttributes
include Aggregations, Transactions, Reflection, Serialization, Store
- NilClass.add_whiner(self) if NilClass.respond_to?(:add_whiner)
-
# Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
# "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)).
# (Alias for the protected read_attribute method).
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb
index ca9fb11e95..7145dc0692 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb
@@ -127,7 +127,7 @@ module ActiveRecord
spec = resolver.spec
unless respond_to?(spec.adapter_method)
- raise AdapterNotFound, "database configuration specifies nonexistent #{spec[:adapter]} adapter"
+ raise AdapterNotFound, "database configuration specifies nonexistent #{spec.config[:adapter]} adapter"
end
remove_connection
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
index dc4a53034b..eb8cff9610 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -130,7 +130,7 @@ module ActiveRecord
#
# In order to get around this problem, #transaction will emulate the effect
# of nested transactions, by using savepoints:
- # http://dev.mysql.com/doc/refman/5.0/en/savepoints.html
+ # http://dev.mysql.com/doc/refman/5.0/en/savepoint.html
# Savepoints are supported by MySQL and PostgreSQL, but not SQLite3.
#
# It is safe to call this method if a database transaction is already open,
@@ -341,7 +341,7 @@ module ActiveRecord
# Send a rollback message to all records after they have been rolled back. If rollback
# is false, only rollback records since the last save point.
- def rollback_transaction_records(rollback) #:nodoc
+ def rollback_transaction_records(rollback)
if rollback
records = @_current_transaction_records.flatten
@_current_transaction_records.clear
@@ -361,7 +361,7 @@ module ActiveRecord
end
# Send a commit message to all records after they have been committed.
- def commit_transaction_records #:nodoc
+ def commit_transaction_records
records = @_current_transaction_records.flatten
@_current_transaction_records.clear
unless records.blank?
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
index 6f135b56b5..132ca10f79 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
@@ -66,6 +66,7 @@ module ActiveRecord
def initialize(base)
@columns = []
+ @columns_hash = {}
@base = base
end
@@ -86,7 +87,7 @@ module ActiveRecord
# Returns a ColumnDefinition for the column with name +name+.
def [](name)
- @columns.find {|column| column.name.to_s == name.to_s}
+ @columns_hash[name.to_s]
end
# Instantiates a new column for the table.
@@ -224,28 +225,31 @@ module ActiveRecord
# t.references :taggable, :polymorphic => { :default => 'Photo' }
# end
def column(name, type, options = {})
- column = self[name] || ColumnDefinition.new(@base, name, type)
- if options[:limit]
- column.limit = options[:limit]
- elsif native[type.to_sym].is_a?(Hash)
- column.limit = native[type.to_sym][:limit]
+ name = name.to_s
+ type = type.to_sym
+
+ column = self[name] || new_column_definition(@base, name, type)
+
+ limit = options.fetch(:limit) do
+ native[type][:limit] if native[type].is_a?(Hash)
end
+
+ column.limit = limit
column.precision = options[:precision]
- column.scale = options[:scale]
- column.default = options[:default]
- column.null = options[:null]
- @columns << column unless @columns.include? column
+ column.scale = options[:scale]
+ column.default = options[:default]
+ column.null = options[:null]
self
end
%w( string text integer float decimal datetime timestamp time date binary boolean ).each do |column_type|
class_eval <<-EOV, __FILE__, __LINE__ + 1
- def #{column_type}(*args) # def string(*args)
- options = args.extract_options! # options = args.extract_options!
- column_names = args # column_names = args
- #
- column_names.each { |name| column(name, '#{column_type}', options) } # column_names.each { |name| column(name, 'string', options) }
- end # end
+ def #{column_type}(*args) # def string(*args)
+ options = args.extract_options! # options = args.extract_options!
+ column_names = args # column_names = args
+ type = :'#{column_type}' # type = :string
+ column_names.each { |name| column(name, type, options) } # column_names.each { |name| column(name, type, options) }
+ end # end
EOV
end
@@ -275,9 +279,16 @@ module ActiveRecord
end
private
- def native
- @base.native_database_types
- end
+ def new_column_definition(base, name, type)
+ definition = ColumnDefinition.new base, name, type
+ @columns << definition
+ @columns_hash[name] = definition
+ definition
+ end
+
+ def native
+ @base.native_database_types
+ end
end
# Represents an SQL table in an abstract way for updating a table.
@@ -453,13 +464,13 @@ module ActiveRecord
def #{column_type}(*args) # def string(*args)
options = args.extract_options! # options = args.extract_options!
column_names = args # column_names = args
- #
+ type = :'#{column_type}' # type = :string
column_names.each do |name| # column_names.each do |name|
- column = ColumnDefinition.new(@base, name, '#{column_type}') # column = ColumnDefinition.new(@base, name, 'string')
+ column = ColumnDefinition.new(@base, name.to_s, type) # column = ColumnDefinition.new(@base, name, type)
if options[:limit] # if options[:limit]
column.limit = options[:limit] # column.limit = options[:limit]
- elsif native['#{column_type}'.to_sym].is_a?(Hash) # elsif native['string'.to_sym].is_a?(Hash)
- column.limit = native['#{column_type}'.to_sym][:limit] # column.limit = native['string'.to_sym][:limit]
+ elsif native[type].is_a?(Hash) # elsif native[type].is_a?(Hash)
+ column.limit = native[type][:limit] # column.limit = native[type][:limit]
end # end
column.precision = options[:precision] # column.precision = options[:precision]
column.scale = options[:scale] # column.scale = options[:scale]
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
index 3ced32e42d..a905c135f8 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -23,12 +23,10 @@ module ActiveRecord
# === Example
# table_exists?(:developers)
def table_exists?(table_name)
- begin
- select_value("SELECT 1 FROM #{quote_table_name(table_name)} where 1=0")
- true
- rescue
- false
- end
+ select_value("SELECT 1 FROM #{quote_table_name(table_name)} where 1=0", 'SCHEMA')
+ true
+ rescue
+ false
end
# Returns an array of indexes for the given table.
diff --git a/activerecord/lib/active_record/connection_adapters/schema_cache.rb b/activerecord/lib/active_record/connection_adapters/schema_cache.rb
index b14b37ce89..bee03abd44 100644
--- a/activerecord/lib/active_record/connection_adapters/schema_cache.rb
+++ b/activerecord/lib/active_record/connection_adapters/schema_cache.rb
@@ -42,10 +42,7 @@ module ActiveRecord
def table_exists?(name)
return @tables[name] if @tables.key? name
- connection.tables.each { |table| @tables[table] = true }
- @tables[name] = connection.table_exists?(name) if !@tables.key?(name)
-
- @tables[name]
+ @tables[name] = connection.table_exists?(name)
end
# Clears out internal caches:
@@ -66,6 +63,7 @@ module ActiveRecord
@columns_hash.delete table_name
@column_defaults.delete table_name
@primary_keys.delete table_name
+ @tables.delete table_name
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
index 386b3f7465..11bb457d03 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
@@ -47,11 +47,7 @@ module ActiveRecord
# Returns the current database encoding format as a string, eg: 'UTF-8'
def encoding
- if @connection.respond_to?(:encoding)
- @connection.encoding.to_s
- else
- @connection.execute('PRAGMA encoding')[0]['encoding']
- end
+ @connection.encoding.to_s
end
end
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index cad9417216..d8340bf1c9 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -22,8 +22,6 @@ else
end
end
-class FixturesFileNotFound < StandardError; end
-
module ActiveRecord
# \Fixtures are a way of organizing data that you want to test against; in short, sample data.
#
@@ -644,14 +642,6 @@ module ActiveRecord
end
def read_fixture_files
- if ::File.file?(yaml_file_path)
- read_yaml_fixture_files
- else
- raise FixturesFileNotFound, "Could not find #{yaml_file_path}"
- end
- end
-
- def read_yaml_fixture_files
yaml_files = Dir["#{@fixture_path}/**/*.yml"].select { |f|
::File.file?(f)
} + [yaml_file_path]
@@ -832,6 +822,7 @@ module ActiveRecord
end
@fixture_cache = {}
+ @fixture_connections = []
@@already_loaded_fixtures ||= {}
# Load fixtures once and begin transaction.
diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb
index d70c7d1d34..46464783fd 100644
--- a/activerecord/lib/active_record/migration.rb
+++ b/activerecord/lib/active_record/migration.rb
@@ -302,7 +302,7 @@ module ActiveRecord
#
# class TenderloveMigration < ActiveRecord::Migration
# def change
- # create_table(:horses) do
+ # create_table(:horses) do |t|
# t.column :content, :text
# t.column :remind_at, :datetime
# end
@@ -443,6 +443,7 @@ module ActiveRecord
say_with_time "#{method}(#{arg_list})" do
unless arguments.empty? || method == :execute
arguments[0] = Migrator.proper_table_name(arguments.first)
+ arguments[1] = Migrator.proper_table_name(arguments.second) if method == :rename_table
end
return super unless connection.respond_to?(method)
connection.send(method, *arguments, &block)
@@ -456,26 +457,28 @@ module ActiveRecord
destination_migrations = ActiveRecord::Migrator.migrations(destination)
last = destination_migrations.last
- sources.each do |name, path|
+ sources.each do |scope, path|
source_migrations = ActiveRecord::Migrator.migrations(path)
source_migrations.each do |migration|
source = File.read(migration.filename)
- source = "# This migration comes from #{name} (originally #{migration.version})\n#{source}"
+ source = "# This migration comes from #{scope} (originally #{migration.version})\n#{source}"
if duplicate = destination_migrations.detect { |m| m.name == migration.name }
- options[:on_skip].call(name, migration) if File.read(duplicate.filename) != source && options[:on_skip]
+ if options[:on_skip] && duplicate.scope != scope.to_s
+ options[:on_skip].call(scope, migration)
+ end
next
end
migration.version = next_migration_number(last ? last.version + 1 : 0).to_i
- new_path = File.join(destination, "#{migration.version}_#{migration.name.underscore}.rb")
+ new_path = File.join(destination, "#{migration.version}_#{migration.name.underscore}.#{scope}.rb")
old_path, migration.filename = migration.filename, new_path
last = migration
- FileUtils.cp(old_path, migration.filename)
+ File.open(migration.filename, "w") { |f| f.write source }
copied << migration
- options[:on_copy].call(name, migration, old_path) if options[:on_copy]
+ options[:on_copy].call(scope, migration, old_path) if options[:on_copy]
destination_migrations << migration
end
end
@@ -494,9 +497,9 @@ module ActiveRecord
# MigrationProxy is used to defer loading of the actual migration classes
# until they are needed
- class MigrationProxy < Struct.new(:name, :version, :filename)
+ class MigrationProxy < Struct.new(:name, :version, :filename, :scope)
- def initialize(name, version, filename)
+ def initialize(name, version, filename, scope)
super
@migration = nil
end
@@ -525,16 +528,16 @@ module ActiveRecord
attr_writer :migrations_paths
alias :migrations_path= :migrations_paths=
- def migrate(migrations_paths, target_version = nil)
+ def migrate(migrations_paths, target_version = nil, &block)
case
when target_version.nil?
- up(migrations_paths, target_version)
+ up(migrations_paths, target_version, &block)
when current_version == 0 && target_version == 0
[]
when current_version > target_version
- down(migrations_paths, target_version)
+ down(migrations_paths, target_version, &block)
else
- up(migrations_paths, target_version)
+ up(migrations_paths, target_version, &block)
end
end
@@ -546,12 +549,12 @@ module ActiveRecord
move(:up, migrations_paths, steps)
end
- def up(migrations_paths, target_version = nil)
- self.new(:up, migrations_paths, target_version).migrate
+ def up(migrations_paths, target_version = nil, &block)
+ self.new(:up, migrations_paths, target_version).migrate(&block)
end
- def down(migrations_paths, target_version = nil)
- self.new(:down, migrations_paths, target_version).migrate
+ def down(migrations_paths, target_version = nil, &block)
+ self.new(:down, migrations_paths, target_version).migrate(&block)
end
def run(direction, migrations_paths, target_version)
@@ -591,15 +594,16 @@ module ActiveRecord
migrations_paths.first
end
- def migrations(paths)
+ def migrations(paths, subdirectories = true)
paths = Array.wrap(paths)
- files = Dir[*paths.map { |p| "#{p}/[0-9]*_*.rb" }]
+ glob = subdirectories ? "**/" : ""
+ files = Dir[*paths.map { |p| "#{p}/#{glob}[0-9]*_*.rb" }]
seen = Hash.new false
migrations = files.map do |file|
- version, name = file.scan(/([0-9]+)_([_a-z0-9]*).rb/).first
+ version, name, scope = file.scan(/([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?.rb/).first
raise IllegalMigrationNameError.new(file) unless version
version = version.to_i
@@ -610,7 +614,7 @@ module ActiveRecord
seen[version] = seen[name] = true
- MigrationProxy.new(name, version, file)
+ MigrationProxy.new(name, version, file, scope)
end
migrations.sort_by(&:version)
@@ -653,7 +657,7 @@ module ActiveRecord
end
end
- def migrate
+ def migrate(&block)
current = migrations.detect { |m| m.version == current_version }
target = migrations.detect { |m| m.version == @target_version }
@@ -670,6 +674,10 @@ module ActiveRecord
ran = []
runnable.each do |migration|
+ if block && !block.call(migration)
+ next
+ end
+
Base.logger.info "Migrating to #{migration.name} (#{migration.version})" if Base.logger
seen = migrated.include?(migration.version.to_i)
diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb
index c2e31579a4..b28e8da24c 100644
--- a/activerecord/lib/active_record/railtie.rb
+++ b/activerecord/lib/active_record/railtie.rb
@@ -94,6 +94,10 @@ module ActiveRecord
end
end
+ initializer "active_record.add_watchable_files" do |app|
+ config.watchable_files.concat ["#{app.root}/db/schema.rb", "#{app.root}/db/structure.sql"]
+ end
+
config.after_initialize do
ActiveSupport.on_load(:active_record) do
instantiate_observers
diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake
index abd71793fd..0aafb5184f 100644
--- a/activerecord/lib/active_record/railties/databases.rake
+++ b/activerecord/lib/active_record/railties/databases.rake
@@ -149,7 +149,9 @@ db_namespace = namespace :db do
desc "Migrate the database (options: VERSION=x, VERBOSE=false)."
task :migrate => [:environment, :load_config] do
ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
- ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
+ ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, ENV["VERSION"] ? ENV["VERSION"].to_i : nil) do |migration|
+ ENV["SCOPE"].blank? || (ENV["SCOPE"] == migration.scope)
+ end
db_namespace['_dump'].invoke
end
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index ae97a3f3ca..2c70d31b94 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -301,7 +301,7 @@ module ActiveRecord
protected
# Save the new record state and id of a record so it can be restored later if a transaction fails.
- def remember_transaction_record_state #:nodoc
+ def remember_transaction_record_state #:nodoc:
@_start_transaction_state ||= {}
@_start_transaction_state[:id] = id if has_attribute?(self.class.primary_key)
unless @_start_transaction_state.include?(:new_record)
@@ -314,7 +314,7 @@ module ActiveRecord
end
# Clear the new record state and id of a record.
- def clear_transaction_record_state #:nodoc
+ def clear_transaction_record_state #:nodoc:
if defined?(@_start_transaction_state)
@_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1
remove_instance_variable(:@_start_transaction_state) if @_start_transaction_state[:level] < 1
@@ -322,7 +322,7 @@ module ActiveRecord
end
# Restore the new record state and id of a record that was previously saved by a call to save_record_state.
- def restore_transaction_record_state(force = false) #:nodoc
+ def restore_transaction_record_state(force = false) #:nodoc:
if defined?(@_start_transaction_state)
@_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1
if @_start_transaction_state[:level] < 1
@@ -341,12 +341,12 @@ module ActiveRecord
end
# Determine if a record was created or destroyed in a transaction. State should be one of :new_record or :destroyed.
- def transaction_record_state(state) #:nodoc
+ def transaction_record_state(state) #:nodoc:
@_start_transaction_state[state] if defined?(@_start_transaction_state)
end
# Determine if a transaction included an action for :create, :update, or :destroy. Used in filtering callbacks.
- def transaction_include_action?(action) #:nodoc
+ def transaction_include_action?(action) #:nodoc:
case action
when :create
transaction_record_state(:new_record)
diff --git a/activerecord/test/cases/associations/extension_test.rb b/activerecord/test/cases/associations/extension_test.rb
index 8dc1423375..395b59258d 100644
--- a/activerecord/test/cases/associations/extension_test.rb
+++ b/activerecord/test/cases/associations/extension_test.rb
@@ -71,6 +71,12 @@ class AssociationsExtensionsTest < ActiveRecord::TestCase
assert_equal 'MyApplication::Business::DeveloperAssociationNameAssociationExtension', extension_name(MyApplication::Business::Developer)
end
+ def test_proxy_association_after_scoped
+ post = posts(:welcome)
+ assert_equal post.association(:comments), post.comments.the_association
+ assert_equal post.association(:comments), post.comments.scoped.the_association
+ end
+
private
def extension_name(model)
diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
index b49510b202..745f7132e7 100644
--- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
@@ -825,12 +825,12 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
# clear cache possibly created by other tests
david.projects.reset_column_information
- # One query for columns, one for primary key
- assert_queries(2) { david.projects.columns; david.projects.columns }
+ # One query for columns, one for primary key, one for table existence
+ assert_queries(3) { david.projects.columns; david.projects.columns }
## and again to verify that reset_column_information clears the cache correctly
david.projects.reset_column_information
- assert_queries(2) { david.projects.columns; david.projects.columns }
+ assert_queries(3) { david.projects.columns; david.projects.columns }
end
def test_attributes_are_being_set_when_initialized_from_habm_association_with_where_clause
diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb
index 7e2dafcd01..99dd74c561 100644
--- a/activerecord/test/cases/fixtures_test.rb
+++ b/activerecord/test/cases/fixtures_test.rb
@@ -179,7 +179,7 @@ class FixturesTest < ActiveRecord::TestCase
#sanity check to make sure that this file never exists
assert Dir[nonexistent_fixture_path+"*"].empty?
- assert_raise(FixturesFileNotFound) do
+ assert_raise(Errno::ENOENT) do
ActiveRecord::Fixtures.new( Account.connection, "companies", 'Company', nonexistent_fixture_path)
end
end
diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb
index 6735bc521b..ae2c230d15 100644
--- a/activerecord/test/cases/helper.rb
+++ b/activerecord/test/cases/helper.rb
@@ -68,14 +68,19 @@ module ActiveRecord
cattr_accessor :log
self.log = []
+ attr_reader :ignore
+
+ def initialize(ignore = self.class.ignored_sql)
+ @ignore = ignore
+ end
+
def call(name, start, finish, message_id, values)
sql = values[:sql]
# FIXME: this seems bad. we should probably have a better way to indicate
# the query was cached
- unless 'CACHE' == values[:name]
- self.class.log << sql unless self.class.ignored_sql.any? { |r| sql =~ r }
- end
+ return if 'CACHE' == values[:name] || ignore.any? { |x| x =~ sql }
+ self.class.log << sql
end
end
diff --git a/activerecord/test/cases/log_subscriber_test.rb b/activerecord/test/cases/log_subscriber_test.rb
index 9e8475465e..e24a5ca5aa 100644
--- a/activerecord/test/cases/log_subscriber_test.rb
+++ b/activerecord/test/cases/log_subscriber_test.rb
@@ -13,6 +13,7 @@ class LogSubscriberTest < ActiveRecord::TestCase
@old_logger = ActiveRecord::Base.logger
@using_identity_map = ActiveRecord::IdentityMap.enabled?
ActiveRecord::IdentityMap.enabled = false
+ Developer.primary_key
super
ActiveRecord::LogSubscriber.attach_to(:active_record)
end
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index 00c811194c..1e68911ab3 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -6,6 +6,8 @@ require 'models/topic'
require 'models/developer'
require MIGRATIONS_ROOT + "/valid/2_we_need_reminders"
+require MIGRATIONS_ROOT + "/rename/1_we_need_things"
+require MIGRATIONS_ROOT + "/rename/2_rename_things"
require MIGRATIONS_ROOT + "/decimal/1_give_me_big_numbers"
if ActiveRecord::Base.connection.supports_migrations?
@@ -13,6 +15,8 @@ if ActiveRecord::Base.connection.supports_migrations?
class Reminder < ActiveRecord::Base; end
+ class Thing < ActiveRecord::Base; end
+
class ActiveRecord::Migration
class << self
attr_accessor :message_count
@@ -57,6 +61,11 @@ if ActiveRecord::Base.connection.supports_migrations?
ActiveRecord::Base.connection.initialize_schema_migrations_table
ActiveRecord::Base.connection.execute "DELETE FROM #{ActiveRecord::Migrator.schema_migrations_table_name}"
+ %w(things awesome_things prefix_things_suffix prefix_awesome_things_suffix).each do |table|
+ Thing.connection.drop_table(table) rescue nil
+ end
+ Thing.reset_column_information
+
%w(reminders people_reminders prefix_reminders_suffix).each do |table|
Reminder.connection.drop_table(table) rescue nil
end
@@ -1226,6 +1235,24 @@ if ActiveRecord::Base.connection.supports_migrations?
assert_raise(ActiveRecord::StatementInvalid) { Reminder.find(:first) }
end
+ def test_filtering_migrations
+ assert !Person.column_methods_hash.include?(:last_name)
+ assert !Reminder.table_exists?
+
+ name_filter = lambda { |migration| migration.name == "ValidPeopleHaveLastNames" }
+ ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", &name_filter)
+
+ Person.reset_column_information
+ assert Person.column_methods_hash.include?(:last_name)
+ assert_raise(ActiveRecord::StatementInvalid) { Reminder.find(:first) }
+
+ ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid", &name_filter)
+
+ Person.reset_column_information
+ assert !Person.column_methods_hash.include?(:last_name)
+ assert_raise(ActiveRecord::StatementInvalid) { Reminder.find(:first) }
+ end
+
class MockMigration < ActiveRecord::Migration
attr_reader :went_up, :went_down
def initialize
@@ -1337,6 +1364,15 @@ if ActiveRecord::Base.connection.supports_migrations?
end
end
+ def test_finds_migrations_in_subdirectories
+ migrations = ActiveRecord::Migrator.new(:up, MIGRATIONS_ROOT + "/valid_with_subdirectories").migrations
+
+ [[1, 'ValidPeopleHaveLastNames'], [2, 'WeNeedReminders'], [3, 'InnocentJointable']].each_with_index do |pair, i|
+ assert_equal migrations[i].version, pair.first
+ assert_equal migrations[i].name, pair.last
+ end
+ end
+
def test_finds_migrations_from_two_directories
directories = [MIGRATIONS_ROOT + '/valid_with_timestamps', MIGRATIONS_ROOT + '/to_copy_with_timestamps']
migrations = ActiveRecord::Migrator.new(:up, directories).migrations
@@ -1534,6 +1570,28 @@ if ActiveRecord::Base.connection.supports_migrations?
Reminder.reset_table_name
end
+ def test_rename_table_with_prefix_and_suffix
+ assert !Thing.table_exists?
+ ActiveRecord::Base.table_name_prefix = 'prefix_'
+ ActiveRecord::Base.table_name_suffix = '_suffix'
+ Thing.reset_table_name
+ Thing.reset_sequence_name
+ WeNeedThings.up
+
+ assert Thing.create("content" => "hello world")
+ assert_equal "hello world", Thing.find(:first).content
+
+ RenameThings.up
+ Thing.table_name = "prefix_awesome_things_suffix"
+
+ assert_equal "hello world", Thing.find(:first).content
+ ensure
+ ActiveRecord::Base.table_name_prefix = ''
+ ActiveRecord::Base.table_name_suffix = ''
+ Thing.reset_table_name
+ Thing.reset_sequence_name
+ end
+
def test_add_drop_table_with_prefix_and_suffix
assert !Reminder.table_exists?
ActiveRecord::Base.table_name_prefix = 'prefix_'
@@ -2068,9 +2126,12 @@ if ActiveRecord::Base.connection.supports_migrations?
@existing_migrations = Dir[@migrations_path + "/*.rb"]
copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy"})
- assert File.exists?(@migrations_path + "/4_people_have_hobbies.rb")
- assert File.exists?(@migrations_path + "/5_people_have_descriptions.rb")
- assert_equal [@migrations_path + "/4_people_have_hobbies.rb", @migrations_path + "/5_people_have_descriptions.rb"], copied.map(&:filename)
+ assert File.exists?(@migrations_path + "/4_people_have_hobbies.bukkits.rb")
+ assert File.exists?(@migrations_path + "/5_people_have_descriptions.bukkits.rb")
+ assert_equal [@migrations_path + "/4_people_have_hobbies.bukkits.rb", @migrations_path + "/5_people_have_descriptions.bukkits.rb"], copied.map(&:filename)
+
+ expected = "# This migration comes from bukkits (originally 1)"
+ assert_equal expected, IO.readlines(@migrations_path + "/4_people_have_hobbies.bukkits.rb")[0].chomp
files_count = Dir[@migrations_path + "/*.rb"].length
copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy"})
@@ -2089,10 +2150,10 @@ if ActiveRecord::Base.connection.supports_migrations?
sources[:bukkits] = MIGRATIONS_ROOT + "/to_copy"
sources[:omg] = MIGRATIONS_ROOT + "/to_copy2"
ActiveRecord::Migration.copy(@migrations_path, sources)
- assert File.exists?(@migrations_path + "/4_people_have_hobbies.rb")
- assert File.exists?(@migrations_path + "/5_people_have_descriptions.rb")
- assert File.exists?(@migrations_path + "/6_create_articles.rb")
- assert File.exists?(@migrations_path + "/7_create_comments.rb")
+ assert File.exists?(@migrations_path + "/4_people_have_hobbies.bukkits.rb")
+ assert File.exists?(@migrations_path + "/5_people_have_descriptions.bukkits.rb")
+ assert File.exists?(@migrations_path + "/6_create_articles.omg.rb")
+ assert File.exists?(@migrations_path + "/7_create_comments.omg.rb")
files_count = Dir[@migrations_path + "/*.rb"].length
ActiveRecord::Migration.copy(@migrations_path, sources)
@@ -2107,10 +2168,10 @@ if ActiveRecord::Base.connection.supports_migrations?
Time.travel_to(Time.utc(2010, 7, 26, 10, 10, 10)) do
copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"})
- assert File.exists?(@migrations_path + "/20100726101010_people_have_hobbies.rb")
- assert File.exists?(@migrations_path + "/20100726101011_people_have_descriptions.rb")
- expected = [@migrations_path + "/20100726101010_people_have_hobbies.rb",
- @migrations_path + "/20100726101011_people_have_descriptions.rb"]
+ assert File.exists?(@migrations_path + "/20100726101010_people_have_hobbies.bukkits.rb")
+ assert File.exists?(@migrations_path + "/20100726101011_people_have_descriptions.bukkits.rb")
+ expected = [@migrations_path + "/20100726101010_people_have_hobbies.bukkits.rb",
+ @migrations_path + "/20100726101011_people_have_descriptions.bukkits.rb"]
assert_equal expected, copied.map(&:filename)
files_count = Dir[@migrations_path + "/*.rb"].length
@@ -2132,10 +2193,10 @@ if ActiveRecord::Base.connection.supports_migrations?
Time.travel_to(Time.utc(2010, 7, 26, 10, 10, 10)) do
copied = ActiveRecord::Migration.copy(@migrations_path, sources)
- assert File.exists?(@migrations_path + "/20100726101010_people_have_hobbies.rb")
- assert File.exists?(@migrations_path + "/20100726101011_people_have_descriptions.rb")
- assert File.exists?(@migrations_path + "/20100726101012_create_articles.rb")
- assert File.exists?(@migrations_path + "/20100726101013_create_comments.rb")
+ assert File.exists?(@migrations_path + "/20100726101010_people_have_hobbies.bukkits.rb")
+ assert File.exists?(@migrations_path + "/20100726101011_people_have_descriptions.bukkits.rb")
+ assert File.exists?(@migrations_path + "/20100726101012_create_articles.omg.rb")
+ assert File.exists?(@migrations_path + "/20100726101013_create_comments.omg.rb")
assert_equal 4, copied.length
files_count = Dir[@migrations_path + "/*.rb"].length
@@ -2152,8 +2213,8 @@ if ActiveRecord::Base.connection.supports_migrations?
Time.travel_to(Time.utc(2010, 2, 20, 10, 10, 10)) do
ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"})
- assert File.exists?(@migrations_path + "/20100301010102_people_have_hobbies.rb")
- assert File.exists?(@migrations_path + "/20100301010103_people_have_descriptions.rb")
+ assert File.exists?(@migrations_path + "/20100301010102_people_have_hobbies.bukkits.rb")
+ assert File.exists?(@migrations_path + "/20100301010103_people_have_descriptions.bukkits.rb")
files_count = Dir[@migrations_path + "/*.rb"].length
copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"})
@@ -2169,15 +2230,34 @@ if ActiveRecord::Base.connection.supports_migrations?
@existing_migrations = Dir[@migrations_path + "/*.rb"]
sources = ActiveSupport::OrderedHash.new
- sources[:bukkits] = sources[:omg] = MIGRATIONS_ROOT + "/to_copy_with_timestamps"
+ sources[:bukkits] = MIGRATIONS_ROOT + "/to_copy_with_timestamps"
+ sources[:omg] = MIGRATIONS_ROOT + "/to_copy_with_name_collision"
skipped = []
on_skip = Proc.new { |name, migration| skipped << "#{name} #{migration.name}" }
copied = ActiveRecord::Migration.copy(@migrations_path, sources, :on_skip => on_skip)
assert_equal 2, copied.length
- assert_equal 2, skipped.length
- assert_equal ["bukkits PeopleHaveHobbies", "bukkits PeopleHaveDescriptions"], skipped
+ assert_equal 1, skipped.length
+ assert_equal ["omg PeopleHaveHobbies"], skipped
+ ensure
+ clear
+ end
+
+ def test_skip_is_not_called_if_migrations_are_from_the_same_plugin
+ @migrations_path = MIGRATIONS_ROOT + "/valid_with_timestamps"
+ @existing_migrations = Dir[@migrations_path + "/*.rb"]
+
+ sources = ActiveSupport::OrderedHash.new
+ sources[:bukkits] = MIGRATIONS_ROOT + "/to_copy_with_timestamps"
+
+ skipped = []
+ on_skip = Proc.new { |name, migration| skipped << "#{name} #{migration.name}" }
+ copied = ActiveRecord::Migration.copy(@migrations_path, sources, :on_skip => on_skip)
+ ActiveRecord::Migration.copy(@migrations_path, sources, :on_skip => on_skip)
+
+ assert_equal 2, copied.length
+ assert_equal 0, skipped.length
ensure
clear
end
@@ -2188,8 +2268,8 @@ if ActiveRecord::Base.connection.supports_migrations?
Time.travel_to(Time.utc(2010, 7, 26, 10, 10, 10)) do
copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"})
- assert File.exists?(@migrations_path + "/20100726101010_people_have_hobbies.rb")
- assert File.exists?(@migrations_path + "/20100726101011_people_have_descriptions.rb")
+ assert File.exists?(@migrations_path + "/20100726101010_people_have_hobbies.bukkits.rb")
+ assert File.exists?(@migrations_path + "/20100726101011_people_have_descriptions.bukkits.rb")
assert_equal 2, copied.length
end
ensure
@@ -2203,8 +2283,8 @@ if ActiveRecord::Base.connection.supports_migrations?
Time.travel_to(Time.utc(2010, 7, 26, 10, 10, 10)) do
copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"})
- assert File.exists?(@migrations_path + "/20100726101010_people_have_hobbies.rb")
- assert File.exists?(@migrations_path + "/20100726101011_people_have_descriptions.rb")
+ assert File.exists?(@migrations_path + "/20100726101010_people_have_hobbies.bukkits.rb")
+ assert File.exists?(@migrations_path + "/20100726101011_people_have_descriptions.bukkits.rb")
assert_equal 2, copied.length
end
ensure
diff --git a/activerecord/test/cases/session_store/session_test.rb b/activerecord/test/cases/session_store/session_test.rb
index 258cee7aba..c206e3de4a 100644
--- a/activerecord/test/cases/session_store/session_test.rb
+++ b/activerecord/test/cases/session_store/session_test.rb
@@ -9,6 +9,7 @@ module ActiveRecord
def setup
super
+ ActiveRecord::Base.connection.schema_cache.clear!
Session.drop_table! if Session.table_exists?
end
diff --git a/activerecord/test/migrations/rename/1_we_need_things.rb b/activerecord/test/migrations/rename/1_we_need_things.rb
new file mode 100644
index 0000000000..cdbe0b1679
--- /dev/null
+++ b/activerecord/test/migrations/rename/1_we_need_things.rb
@@ -0,0 +1,11 @@
+class WeNeedThings < ActiveRecord::Migration
+ def self.up
+ create_table("things") do |t|
+ t.column :content, :text
+ end
+ end
+
+ def self.down
+ drop_table "things"
+ end
+end \ No newline at end of file
diff --git a/activerecord/test/migrations/rename/2_rename_things.rb b/activerecord/test/migrations/rename/2_rename_things.rb
new file mode 100644
index 0000000000..d441b71fc9
--- /dev/null
+++ b/activerecord/test/migrations/rename/2_rename_things.rb
@@ -0,0 +1,9 @@
+class RenameThings < ActiveRecord::Migration
+ def self.up
+ rename_table "things", "awesome_things"
+ end
+
+ def self.down
+ rename_table "awesome_things", "things"
+ end
+end \ No newline at end of file
diff --git a/activerecord/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb b/activerecord/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb
new file mode 100644
index 0000000000..e438cf5999
--- /dev/null
+++ b/activerecord/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb
@@ -0,0 +1,9 @@
+class PeopleHaveLastNames < ActiveRecord::Migration
+ def self.up
+ add_column "people", "hobbies", :string
+ end
+
+ def self.down
+ remove_column "people", "hobbies"
+ end
+end
diff --git a/activerecord/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb b/activerecord/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb
new file mode 100644
index 0000000000..06cb911117
--- /dev/null
+++ b/activerecord/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb
@@ -0,0 +1,9 @@
+class ValidPeopleHaveLastNames < ActiveRecord::Migration
+ def self.up
+ add_column "people", "last_name", :string
+ end
+
+ def self.down
+ remove_column "people", "last_name"
+ end
+end
diff --git a/activerecord/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb b/activerecord/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb
new file mode 100644
index 0000000000..d5e71ce8ef
--- /dev/null
+++ b/activerecord/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb
@@ -0,0 +1,12 @@
+class WeNeedReminders < ActiveRecord::Migration
+ def self.up
+ create_table("reminders") do |t|
+ t.column :content, :text
+ t.column :remind_at, :datetime
+ end
+ end
+
+ def self.down
+ drop_table "reminders"
+ end
+end \ No newline at end of file
diff --git a/activerecord/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb b/activerecord/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb
new file mode 100644
index 0000000000..21c9ca5328
--- /dev/null
+++ b/activerecord/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb
@@ -0,0 +1,12 @@
+class InnocentJointable < ActiveRecord::Migration
+ def self.up
+ create_table("people_reminders", :id => false) do |t|
+ t.column :reminder_id, :integer
+ t.column :person_id, :integer
+ end
+ end
+
+ def self.down
+ drop_table "people_reminders"
+ end
+end \ No newline at end of file
diff --git a/activerecord/test/models/post.rb b/activerecord/test/models/post.rb
index 137cee3752..1cab78d8c7 100644
--- a/activerecord/test/models/post.rb
+++ b/activerecord/test/models/post.rb
@@ -44,6 +44,10 @@ class Post < ActiveRecord::Base
def newest
created.last
end
+
+ def the_association
+ proxy_association
+ end
end
has_many :author_favorites, :through => :author
@@ -185,4 +189,4 @@ end
class SpecialPostWithDefaultScope < ActiveRecord::Base
self.table_name = 'posts'
default_scope where(:id => [1, 5,6])
-end \ No newline at end of file
+end