aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/Rakefile2
-rw-r--r--activerecord/lib/active_record/associations/association_collection.rb14
-rw-r--r--activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb10
-rw-r--r--activerecord/lib/active_record/associations/has_many_association.rb10
-rw-r--r--activerecord/lib/active_record/associations/has_many_through_association.rb10
-rw-r--r--activerecord/lib/active_record/associations/through_association_scope.rb7
-rwxr-xr-xactiverecord/lib/active_record/base.rb32
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb2
-rwxr-xr-xactiverecord/lib/active_record/connection_adapters/abstract_adapter.rb7
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql_adapter.rb13
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb12
-rw-r--r--activerecord/lib/active_record/version.rb6
-rw-r--r--activerecord/test/cases/adapter_test.rb15
-rw-r--r--activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb7
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb5
-rw-r--r--activerecord/test/cases/associations/has_many_through_associations_test.rb6
-rwxr-xr-xactiverecord/test/cases/base_test.rb10
-rw-r--r--activerecord/test/cases/calculations_test.rb4
-rw-r--r--activerecord/test/cases/finder_test.rb4
-rw-r--r--activerecord/test/cases/helper.rb2
-rw-r--r--activerecord/test/cases/inheritance_test.rb4
-rw-r--r--activerecord/test/cases/migration_test.rb33
-rw-r--r--activerecord/test/cases/reflection_test.rb12
-rw-r--r--activerecord/test/fixtures/companies.yml8
-rw-r--r--activerecord/test/models/company.rb4
-rw-r--r--activerecord/test/models/post.rb2
-rw-r--r--activerecord/test/models/project.rb6
-rw-r--r--activerecord/test/schema/schema.rb1
29 files changed, 207 insertions, 52 deletions
diff --git a/activerecord/Rakefile b/activerecord/Rakefile
index 0b3f50d17e..0d33b9d516 100644
--- a/activerecord/Rakefile
+++ b/activerecord/Rakefile
@@ -187,7 +187,7 @@ spec = Gem::Specification.new do |s|
s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
end
- s.add_dependency('activesupport', '= 2.3.2' + PKG_BUILD)
+ s.add_dependency('activesupport', '= 3.0.pre' + PKG_BUILD)
s.files.delete FIXTURES_ROOT + "/fixture_database.sqlite"
s.files.delete FIXTURES_ROOT + "/fixture_database_2.sqlite"
diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb
index e12f6be35d..84edaec15e 100644
--- a/activerecord/lib/active_record/associations/association_collection.rb
+++ b/activerecord/lib/active_record/associations/association_collection.rb
@@ -351,7 +351,19 @@ module ActiveRecord
protected
def construct_find_options!(options)
end
-
+
+ def construct_counter_sql
+ if @reflection.options[:counter_sql]
+ @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
+ elsif @reflection.options[:finder_sql]
+ # replace the SELECT clause with COUNT(*), preserving any hints within /* ... */
+ @reflection.options[:counter_sql] = @reflection.options[:finder_sql].sub(/SELECT\b(\/\*.*?\*\/ )?(.*)\bFROM\b/im) { "SELECT #{$1}COUNT(*) FROM" }
+ @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
+ else
+ @counter_sql = @finder_sql
+ end
+ end
+
def load_target
if !@owner.new_record? || foreign_key_present
begin
diff --git a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
index af9ce3dfb2..fd23e59e82 100644
--- a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
+++ b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
@@ -85,15 +85,7 @@ module ActiveRecord
@join_sql = "INNER JOIN #{@owner.connection.quote_table_name @reflection.options[:join_table]} ON #{@reflection.quoted_table_name}.#{@reflection.klass.primary_key} = #{@owner.connection.quote_table_name @reflection.options[:join_table]}.#{@reflection.association_foreign_key}"
- if @reflection.options[:counter_sql]
- @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
- elsif @reflection.options[:finder_sql]
- # replace the SELECT clause with COUNT(*), preserving any hints within /* ... */
- @reflection.options[:counter_sql] = @reflection.options[:finder_sql].sub(/SELECT (\/\*.*?\*\/ )?(.*)\bFROM\b/im) { "SELECT #{$1}COUNT(*) FROM" }
- @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
- else
- @counter_sql = @finder_sql
- end
+ construct_counter_sql
end
def construct_scope
diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb
index 73dd50dd07..e4b631bc54 100644
--- a/activerecord/lib/active_record/associations/has_many_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_association.rb
@@ -97,15 +97,7 @@ module ActiveRecord
@finder_sql << " AND (#{conditions})" if conditions
end
- if @reflection.options[:counter_sql]
- @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
- elsif @reflection.options[:finder_sql]
- # replace the SELECT clause with COUNT(*), preserving any hints within /* ... */
- @reflection.options[:counter_sql] = @reflection.options[:finder_sql].sub(/SELECT (\/\*.*?\*\/ )?(.*)\bFROM\b/im) { "SELECT #{$1}COUNT(*) FROM" }
- @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
- else
- @counter_sql = @finder_sql
- end
+ construct_counter_sql
end
def construct_scope
diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb
index 67631f0120..e21ef90391 100644
--- a/activerecord/lib/active_record/associations/has_many_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_through_association.rb
@@ -90,15 +90,7 @@ module ActiveRecord
@finder_sql = construct_conditions
end
- if @reflection.options[:counter_sql]
- @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
- elsif @reflection.options[:finder_sql]
- # replace the SELECT clause with COUNT(*), preserving any hints within /* ... */
- @reflection.options[:counter_sql] = @reflection.options[:finder_sql].sub(/SELECT (\/\*.*?\*\/ )?(.*)\bFROM\b/im) { "SELECT #{$1}COUNT(*) FROM" }
- @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
- else
- @counter_sql = @finder_sql
- end
+ construct_counter_sql
end
def has_cached_counter?
diff --git a/activerecord/lib/active_record/associations/through_association_scope.rb b/activerecord/lib/active_record/associations/through_association_scope.rb
index 7661c50039..8e7ce33814 100644
--- a/activerecord/lib/active_record/associations/through_association_scope.rb
+++ b/activerecord/lib/active_record/associations/through_association_scope.rb
@@ -94,10 +94,17 @@ module ActiveRecord
def construct_join_attributes(associate)
# TODO: revist this to allow it for deletion, supposing dependent option is supported
raise ActiveRecord::HasManyThroughCantAssociateThroughHasManyReflection.new(@owner, @reflection) if @reflection.source_reflection.macro == :has_many
+
join_attributes = construct_owner_attributes(@reflection.through_reflection).merge(@reflection.source_reflection.primary_key_name => associate.id)
+
if @reflection.options[:source_type]
join_attributes.merge!(@reflection.source_reflection.options[:foreign_type] => associate.class.base_class.name.to_s)
end
+
+ if @reflection.through_reflection.options[:conditions].is_a?(Hash)
+ join_attributes.merge!(@reflection.through_reflection.options[:conditions])
+ end
+
join_attributes
end
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 39fac0b7e7..deab56e219 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -67,6 +67,25 @@ module ActiveRecord #:nodoc:
class StatementInvalid < ActiveRecordError
end
+ # Parent class for all specific exceptions which wrap database driver exceptions
+ # provides access to the original exception also.
+ class WrappedDatabaseException < StatementInvalid
+ attr_reader :original_exception
+
+ def initialize(message, original_exception)
+ super(message)
+ @original_exception, = original_exception
+ end
+ end
+
+ # Raised when a record cannot be inserted because it would violate a uniqueness constraint.
+ class RecordNotUnique < WrappedDatabaseException
+ end
+
+ # Raised when a record cannot be inserted or updated because it references a non-existent record.
+ class InvalidForeignKey < WrappedDatabaseException
+ end
+
# Raised when number of bind variables in statement given to <tt>:condition</tt> key (for example, when using +find+ method)
# does not match number of expected variables.
#
@@ -1385,14 +1404,14 @@ module ActiveRecord #:nodoc:
end
# Transform the modelname into a more humane format, using I18n.
- # Defaults to the basic humanize method.
+ # By default, it will underscore then humanize the class name (BlogPost.human_name #=> "Blog post").
# Default scope of the translation is activerecord.models
# Specify +options+ with additional translating options.
def human_name(options = {})
defaults = self_and_descendants_from_active_record.map do |klass|
:"#{klass.name.underscore}"
- end
- defaults << self.name.humanize
+ end
+ defaults << self.name.underscore.humanize
I18n.translate(defaults.shift, {:scope => [:activerecord, :models], :count => 1, :default => defaults}.merge(options))
end
@@ -2851,6 +2870,13 @@ module ActiveRecord #:nodoc:
@attributes.frozen?
end
+ # Returns duplicated record with unfreezed attributes.
+ def dup
+ obj = super
+ obj.instance_variable_set('@attributes', instance_variable_get('@attributes').dup)
+ obj
+ end
+
# Returns +true+ if the record is read only. Records loaded through joins with piggy-back
# attributes will be marked as read only since they cannot be saved.
def readonly?
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 ff63ea3a2e..f44cd0bd5a 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -101,7 +101,7 @@ module ActiveRecord
table_definition = TableDefinition.new(self)
table_definition.primary_key(options[:primary_key] || Base.get_primary_key(table_name)) unless options[:id] == false
- yield table_definition
+ yield table_definition if block_given?
if options[:force] && table_exists?(table_name)
drop_table(table_name, options)
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index 91b111ab55..c533d4cdb6 100755
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -211,9 +211,14 @@ module ActiveRecord
@last_verification = 0
message = "#{e.class.name}: #{e.message}: #{sql}"
log_info(message, name, 0)
- raise ActiveRecord::StatementInvalid, message
+ raise translate_exception(e, message)
end
+ def translate_exception(e, message)
+ # override in derived class
+ ActiveRecord::StatementInvalid.new(message)
+ end
+
def format_log_entry(message, dump = nil)
if ActiveRecord::Base.colorize_logging
if @@row_even
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index d5536e4d67..83cb9cff15 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -563,6 +563,19 @@ module ActiveRecord
where_sql
end
+ protected
+
+ def translate_exception(exception, message)
+ case exception.errno
+ when 1062
+ RecordNotUnique.new(message, exception)
+ when 1452
+ InvalidForeignKey.new(message, exception)
+ else
+ super
+ end
+ end
+
private
def connect
encoding = @config[:encoding]
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 18b499904e..e77ae93c21 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -941,6 +941,17 @@ module ActiveRecord
end
end
+ def translate_exception(exception, message)
+ case exception.message
+ when /duplicate key value violates unique constraint/
+ RecordNotUnique.new(message, exception)
+ when /violates foreign key constraint/
+ InvalidForeignKey.new(message, exception)
+ else
+ super
+ end
+ end
+
private
# The internal PostgreSQL identifier of the money data type.
MONEY_COLUMN_TYPE_OID = 790 #:nodoc:
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index c9d0c9574f..5e5e30776a 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -245,7 +245,7 @@ module ActiveRecord
end
def rename_table(name, new_name)
- execute "ALTER TABLE #{name} RENAME TO #{new_name}"
+ execute "ALTER TABLE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}"
end
# See: http://www.sqlite.org/lang_altertable.html
@@ -431,6 +431,16 @@ module ActiveRecord
'INTEGER PRIMARY KEY NOT NULL'.freeze
end
end
+
+ def translate_exception(exception, message)
+ case exception.message
+ when /column(s)? .* (is|are) not unique/
+ RecordNotUnique.new(message, exception)
+ else
+ super
+ end
+ end
+
end
class SQLite2Adapter < SQLiteAdapter # :nodoc:
diff --git a/activerecord/lib/active_record/version.rb b/activerecord/lib/active_record/version.rb
index 852807b4c5..10ef9d7594 100644
--- a/activerecord/lib/active_record/version.rb
+++ b/activerecord/lib/active_record/version.rb
@@ -1,8 +1,8 @@
module ActiveRecord
module VERSION #:nodoc:
- MAJOR = 2
- MINOR = 3
- TINY = 2
+ MAJOR = 3
+ MINOR = 0
+ TINY = "pre"
STRING = [MAJOR, MINOR, TINY].join('.')
end
diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb
index 04770646b2..80530194ff 100644
--- a/activerecord/test/cases/adapter_test.rb
+++ b/activerecord/test/cases/adapter_test.rb
@@ -130,4 +130,19 @@ class AdapterTest < ActiveRecord::TestCase
assert_equal " LIMIT 1,7 OFFSET 7", @connection.add_limit_offset!("", :limit=>sql_inject, :offset=>7)
end
end
+
+ def test_uniqueness_violations_are_translated_to_specific_exception
+ @connection.execute "INSERT INTO subscribers(nick) VALUES('me')"
+ assert_raises(ActiveRecord::RecordNotUnique) do
+ @connection.execute "INSERT INTO subscribers(nick) VALUES('me')"
+ end
+ end
+
+ def test_foreign_key_violations_are_translated_to_specific_exception
+ unless @connection.adapter_name == 'SQLite'
+ assert_raises(ActiveRecord::InvalidForeignKey) do
+ @connection.execute "INSERT INTO fk_test_has_fk (fk_id) VALUES (0)"
+ end
+ end
+ end
end
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 8dc95806b9..14b96caaae 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
@@ -803,6 +803,13 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
assert_equal 1, developer.projects.count
end
+ unless current_adapter?(:PostgreSQLAdapter)
+ def test_count_with_finder_sql
+ assert_equal 3, projects(:active_record).developers_with_finder_sql.count
+ assert_equal 3, projects(:active_record).developers_with_multiline_finder_sql.count
+ end
+ end
+
def test_association_proxy_transaction_method_starts_transaction_in_association_class
Post.expects(:transaction)
Category.find(:first).posts.transaction do
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index d99424f9cd..15919e2289 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -163,6 +163,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal 0, Firm.find(:first).no_clients_using_counter_sql.size
end
+ def test_counting_using_finder_sql
+ assert_equal 2, Firm.find(4).clients_using_sql.count
+ assert_equal 2, Firm.find(4).clients_using_multiline_sql.count
+ end
+
def test_belongs_to_sanity
c = Client.new
assert_nil c.firm
diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb
index 4254badef2..7a4712d7c8 100644
--- a/activerecord/test/cases/associations/has_many_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb
@@ -157,6 +157,12 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
assert_equal peeps + 1, posts(:thinking).people.count
end
+ def test_associate_with_create_with_through_having_conditions
+ impatient_people = posts(:thinking).impatient_people.count
+ posts(:thinking).impatient_people.create!(:first_name => 'foo')
+ assert_equal impatient_people + 1, posts(:thinking).impatient_people.count
+ end
+
def test_associate_with_create_exclamation_and_no_options
peeps = posts(:thinking).people.count
posts(:thinking).people.create!(:first_name => 'foo')
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 96270118d8..f9ac37cc87 100755
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -599,9 +599,9 @@ class BasicsTest < ActiveRecord::TestCase
end
def test_destroy_many
- assert_equal 3, Client.count
- Client.destroy([2, 3])
- assert_equal 1, Client.count
+ assert_difference('Client.count', -2) do
+ Client.destroy([2, 3])
+ end
end
def test_delete_many
@@ -2116,4 +2116,8 @@ class BasicsTest < ActiveRecord::TestCase
assert_equal custom_datetime, parrot[attribute]
end
end
+
+ def test_dup
+ assert !Minimalistic.new.freeze.dup.frozen?
+ end
end
diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb
index fd455e0864..75f52dfa4a 100644
--- a/activerecord/test/cases/calculations_test.rb
+++ b/activerecord/test/cases/calculations_test.rb
@@ -203,7 +203,7 @@ class CalculationsTest < ActiveRecord::TestCase
c = Company.count(:all, :group => "UPPER(#{QUOTED_TYPE})")
assert_equal 2, c[nil]
assert_equal 1, c['DEPENDENTFIRM']
- assert_equal 3, c['CLIENT']
+ assert_equal 4, c['CLIENT']
assert_equal 2, c['FIRM']
end
@@ -211,7 +211,7 @@ class CalculationsTest < ActiveRecord::TestCase
c = Company.count(:all, :group => "UPPER(companies.#{QUOTED_TYPE})")
assert_equal 2, c[nil]
assert_equal 1, c['DEPENDENTFIRM']
- assert_equal 3, c['CLIENT']
+ assert_equal 4, c['CLIENT']
assert_equal 2, c['FIRM']
end
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index 037b67ec84..d8f5695a0f 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -1044,8 +1044,8 @@ class FinderTest < ActiveRecord::TestCase
end
def test_select_values
- assert_equal ["1","2","3","4","5","6","7","8","9"], Company.connection.select_values("SELECT id FROM companies ORDER BY id").map! { |i| i.to_s }
- assert_equal ["37signals","Summit","Microsoft", "Flamboyant Software", "Ex Nihilo", "RailsCore", "Leetsoft", "Jadedpixel", "Odegy"], Company.connection.select_values("SELECT name FROM companies ORDER BY id")
+ assert_equal ["1","2","3","4","5","6","7","8","9", "10"], Company.connection.select_values("SELECT id FROM companies ORDER BY id").map! { |i| i.to_s }
+ assert_equal ["37signals","Summit","Microsoft", "Flamboyant Software", "Ex Nihilo", "RailsCore", "Leetsoft", "Jadedpixel", "Odegy", "Ex Nihilo Part Deux"], Company.connection.select_values("SELECT name FROM companies ORDER BY id")
end
def test_select_rows
diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb
index c30186286d..d1e7caed89 100644
--- a/activerecord/test/cases/helper.rb
+++ b/activerecord/test/cases/helper.rb
@@ -6,8 +6,6 @@ require 'config'
require 'rubygems'
require 'test/unit'
require 'stringio'
-gem 'mocha', '>= 0.9.5'
-require 'mocha'
require 'active_record'
require 'active_record/test_case'
diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb
index eae5a60829..167d3abad9 100644
--- a/activerecord/test/cases/inheritance_test.rb
+++ b/activerecord/test/cases/inheritance_test.rb
@@ -112,9 +112,9 @@ class InheritanceTest < ActiveRecord::TestCase
end
def test_inheritance_condition
- assert_equal 9, Company.count
+ assert_equal 10, Company.count
assert_equal 2, Firm.count
- assert_equal 3, Client.count
+ assert_equal 4, Client.count
end
def test_alt_inheritance_condition
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index 16861f21b1..215b5a427a 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -293,6 +293,13 @@ if ActiveRecord::Base.connection.supports_migrations?
Person.connection.drop_table table_name rescue nil
end
+ def test_create_table_without_a_block
+ table_name = :testings
+ Person.connection.create_table table_name
+ ensure
+ Person.connection.drop_table table_name rescue nil
+ end
+
# Sybase, and SQLite3 will not allow you to add a NOT NULL
# column to a table without a default value.
unless current_adapter?(:SybaseAdapter, :SQLiteAdapter)
@@ -635,6 +642,32 @@ if ActiveRecord::Base.connection.supports_migrations?
end
end
+ if current_adapter?(:SQLiteAdapter)
+ def test_rename_table_for_sqlite_should_work_with_reserved_words
+ begin
+ assert_nothing_raised do
+ ActiveRecord::Base.connection.rename_table :references, :old_references
+ ActiveRecord::Base.connection.create_table :octopuses do |t|
+ t.column :url, :string
+ end
+ end
+
+ assert_nothing_raised { ActiveRecord::Base.connection.rename_table :octopuses, :references }
+
+ # Using explicit id in insert for compatibility across all databases
+ con = ActiveRecord::Base.connection
+ assert_nothing_raised do
+ con.execute "INSERT INTO 'references' (#{con.quote_column_name('id')}, #{con.quote_column_name('url')}) VALUES (1, 'http://rubyonrails.com')"
+ end
+ assert_equal 'http://rubyonrails.com', ActiveRecord::Base.connection.select_value("SELECT url FROM 'references' WHERE id=1")
+
+ ensure
+ ActiveRecord::Base.connection.drop_table :references
+ ActiveRecord::Base.connection.rename_table :old_references, :references
+ end
+ end
+ end
+
def test_rename_table
begin
ActiveRecord::Base.connection.create_table :octopuses do |t|
diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb
index db64bbb806..194d5e9dff 100644
--- a/activerecord/test/cases/reflection_test.rb
+++ b/activerecord/test/cases/reflection_test.rb
@@ -5,14 +5,20 @@ require 'models/company'
require 'models/company_in_module'
require 'models/subscriber'
require 'models/pirate'
+require 'models/price_estimate'
class ReflectionTest < ActiveRecord::TestCase
- fixtures :topics, :customers, :companies, :subscribers
+ fixtures :topics, :customers, :companies, :subscribers, :price_estimates
def setup
@first = Topic.find(1)
end
+ def test_human_name
+ assert_equal "Price estimate", PriceEstimate.human_name
+ assert_equal "Subscriber", Subscriber.human_name
+ end
+
def test_column_null_not_null
subscriber = Subscriber.find(:first)
assert subscriber.column_for_attribute("name").null
@@ -170,8 +176,8 @@ class ReflectionTest < ActiveRecord::TestCase
def test_reflection_of_all_associations
# FIXME these assertions bust a lot
- assert_equal 28, Firm.reflect_on_all_associations.size
- assert_equal 21, Firm.reflect_on_all_associations(:has_many).size
+ assert_equal 29, Firm.reflect_on_all_associations.size
+ assert_equal 22, Firm.reflect_on_all_associations(:has_many).size
assert_equal 7, Firm.reflect_on_all_associations(:has_one).size
assert_equal 0, Firm.reflect_on_all_associations(:belongs_to).size
end
diff --git a/activerecord/test/fixtures/companies.yml b/activerecord/test/fixtures/companies.yml
index e7691fde46..9ad68fbe11 100644
--- a/activerecord/test/fixtures/companies.yml
+++ b/activerecord/test/fixtures/companies.yml
@@ -35,6 +35,14 @@ another_client:
name: Ex Nihilo
ruby_type: Client
+a_third_client:
+ id: 10
+ type: Client
+ firm_id: 4
+ client_of: 4
+ name: Ex Nihilo Part Deux
+ ruby_type: Client
+
rails_core:
id: 6
name: RailsCore
diff --git a/activerecord/test/models/company.rb b/activerecord/test/models/company.rb
index 4c2514b0b3..840527ddeb 100644
--- a/activerecord/test/models/company.rb
+++ b/activerecord/test/models/company.rb
@@ -48,6 +48,10 @@ class Firm < Company
has_many :clients_with_interpolated_conditions, :class_name => "Client", :conditions => 'rating > #{rating}'
has_many :clients_like_ms_with_hash_conditions, :conditions => { :name => 'Microsoft' }, :class_name => "Client", :order => "id"
has_many :clients_using_sql, :class_name => "Client", :finder_sql => 'SELECT * FROM companies WHERE client_of = #{id}'
+ has_many :clients_using_multiline_sql, :class_name => "Client", :finder_sql => '
+ SELECT
+ companies.*
+ FROM companies WHERE companies.client_of = #{id}'
has_many :clients_using_counter_sql, :class_name => "Client",
:finder_sql => 'SELECT * FROM companies WHERE client_of = #{id}',
:counter_sql => 'SELECT COUNT(*) FROM companies WHERE client_of = #{id}'
diff --git a/activerecord/test/models/post.rb b/activerecord/test/models/post.rb
index 374e536a5b..7392515ec7 100644
--- a/activerecord/test/models/post.rb
+++ b/activerecord/test/models/post.rb
@@ -69,6 +69,8 @@ class Post < ActiveRecord::Base
:after_add => lambda {|owner, reader| log(:added, :after, reader.first_name) },
:before_remove => lambda {|owner, reader| log(:removed, :before, reader.first_name) },
:after_remove => lambda {|owner, reader| log(:removed, :after, reader.first_name) }
+ has_many :skimmers, :class_name => 'Reader', :conditions => { :skimmer => true }
+ has_many :impatient_people, :through => :skimmers, :source => :person
def self.top(limit)
ranked_by_comments.limit(limit)
diff --git a/activerecord/test/models/project.rb b/activerecord/test/models/project.rb
index f25b2ddf77..422b12dc83 100644
--- a/activerecord/test/models/project.rb
+++ b/activerecord/test/models/project.rb
@@ -8,6 +8,12 @@ class Project < ActiveRecord::Base
has_and_belongs_to_many :developers_named_david_with_hash_conditions, :class_name => "Developer", :conditions => { :name => 'David' }, :uniq => true
has_and_belongs_to_many :salaried_developers, :class_name => "Developer", :conditions => "salary > 0"
has_and_belongs_to_many :developers_with_finder_sql, :class_name => "Developer", :finder_sql => 'SELECT t.*, j.* FROM developers_projects j, developers t WHERE t.id = j.developer_id AND j.project_id = #{id} ORDER BY t.id'
+ has_and_belongs_to_many :developers_with_multiline_finder_sql, :class_name => "Developer", :finder_sql => '
+ SELECT
+ t.*, j.*
+ FROM
+ developers_projects j,
+ developers t WHERE t.id = j.developer_id AND j.project_id = #{id} ORDER BY t.id'
has_and_belongs_to_many :developers_by_sql, :class_name => "Developer", :delete_sql => "DELETE FROM developers_projects WHERE project_id = \#{id} AND developer_id = \#{record.id}"
has_and_belongs_to_many :developers_with_callbacks, :class_name => "Developer", :before_add => Proc.new {|o, r| o.developers_log << "before_adding#{r.id || '<new>'}"},
:after_add => Proc.new {|o, r| o.developers_log << "after_adding#{r.id || '<new>'}"},
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index b2aaccb352..d2d6d1f4b3 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -364,6 +364,7 @@ ActiveRecord::Schema.define do
create_table :readers, :force => true do |t|
t.integer :post_id, :null => false
t.integer :person_id, :null => false
+ t.boolean :skimmer, :default => false
end
create_table :shape_expressions, :force => true do |t|