aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorHongli Lai (Phusion) <hongli@phusion.nl>2008-12-03 19:30:35 +0100
committerHongli Lai (Phusion) <hongli@phusion.nl>2008-12-03 19:30:35 +0100
commitccb96f2297e8783165cba764e9b5d51e1a15ff87 (patch)
tree3229e6fdddc42054615514d843c555e341003033 /activerecord
parentfb2325e35855d62abd2c76ce03feaa3ca7992e4f (diff)
parent761a633a9c0a45d76ef3ed10da97e3696c3ded79 (diff)
downloadrails-ccb96f2297e8783165cba764e9b5d51e1a15ff87.tar.gz
rails-ccb96f2297e8783165cba764e9b5d51e1a15ff87.tar.bz2
rails-ccb96f2297e8783165cba764e9b5d51e1a15ff87.zip
Merge commit 'origin/master' into savepoints
Conflicts: activerecord/lib/active_record/fixtures.rb activerecord/test/cases/defaults_test.rb
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG20
-rw-r--r--activerecord/Rakefile2
-rw-r--r--activerecord/lib/active_record.rb82
-rw-r--r--activerecord/lib/active_record/association_preload.rb4
-rwxr-xr-xactiverecord/lib/active_record/associations.rb37
-rw-r--r--activerecord/lib/active_record/associations/association_proxy.rb1
-rw-r--r--activerecord/lib/active_record/associations/has_one_through_association.rb7
-rwxr-xr-xactiverecord/lib/active_record/base.rb54
-rw-r--r--activerecord/lib/active_record/calculations.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb22
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb8
-rwxr-xr-xactiverecord/lib/active_record/connection_adapters/abstract_adapter.rb6
-rw-r--r--activerecord/lib/active_record/fixtures.rb289
-rw-r--r--activerecord/lib/active_record/locale/en.yml (renamed from activerecord/lib/active_record/locale/en-US.yml)2
-rw-r--r--activerecord/lib/active_record/serialization.rb4
-rw-r--r--activerecord/lib/active_record/test_case.rb16
-rw-r--r--activerecord/lib/active_record/version.rb2
-rw-r--r--activerecord/test/cases/adapter_test_sqlserver.rb95
-rw-r--r--activerecord/test/cases/ar_schema_test.rb1
-rw-r--r--activerecord/test/cases/associations/eager_test.rb22
-rw-r--r--activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb28
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb5
-rw-r--r--activerecord/test/cases/associations/has_one_through_associations_test.rb40
-rwxr-xr-xactiverecord/test/cases/base_test.rb13
-rw-r--r--activerecord/test/cases/binary_test.rb6
-rw-r--r--activerecord/test/cases/calculations_test.rb5
-rw-r--r--activerecord/test/cases/defaults_test.rb7
-rw-r--r--activerecord/test/cases/finder_test.rb7
-rw-r--r--activerecord/test/cases/fixtures_test.rb8
-rw-r--r--activerecord/test/cases/helper.rb29
-rw-r--r--activerecord/test/cases/i18n_test.rb12
-rw-r--r--activerecord/test/cases/inheritance_test.rb4
-rw-r--r--activerecord/test/cases/locking_test.rb4
-rw-r--r--activerecord/test/cases/method_scoping_test.rb67
-rw-r--r--activerecord/test/cases/migration_test.rb10
-rw-r--r--activerecord/test/cases/pooled_connections_test.rb24
-rw-r--r--activerecord/test/cases/schema_dumper_test.rb1
-rw-r--r--activerecord/test/cases/table_name_test_sqlserver.rb23
-rw-r--r--activerecord/test/cases/validations_i18n_test.rb98
-rw-r--r--activerecord/test/fixtures/organizations.yml5
-rw-r--r--activerecord/test/models/author.rb1
-rw-r--r--activerecord/test/models/category.rb1
-rw-r--r--activerecord/test/models/developer.rb12
-rw-r--r--activerecord/test/models/member.rb2
-rw-r--r--activerecord/test/models/member_detail.rb4
-rw-r--r--activerecord/test/models/organization.rb4
-rw-r--r--activerecord/test/models/project.rb1
-rw-r--r--activerecord/test/schema/schema.rb10
-rw-r--r--activerecord/test/schema/sqlserver_specific_schema.rb5
49 files changed, 631 insertions, 481 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index 4ca062b535..cca70f1fb7 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,4 +1,22 @@
-*2.2.1 [RC2 or 2.2 final]*
+*2.3.0/3.0*
+
+* Add :having as a key to find and the relevant associations. [miloops]
+
+* Added default_scope to Base #1381 [Paweł Kondzior]. Example:
+
+ class Person < ActiveRecord::Base
+ default_scope :order => 'last_name, first_name'
+ end
+
+ class Company < ActiveRecord::Base
+ has_many :people
+ end
+
+ Person.all # => Person.find(:all, :order => 'last_name, first_name')
+ Company.find(1).people # => Person.find(:all, :order => 'last_name, first_name', :conditions => { :company_id => 1 })
+
+
+*2.2.1 [RC2] (November 14th, 2008)*
* Ensure indices don't flip order in schema.rb #1266 [Jordi Bunster]
diff --git a/activerecord/Rakefile b/activerecord/Rakefile
index f192646547..f47674d5b7 100644
--- a/activerecord/Rakefile
+++ b/activerecord/Rakefile
@@ -171,7 +171,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.2.0' + PKG_BUILD)
+ s.add_dependency('activesupport', '= 2.3.0' + 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.rb b/activerecord/lib/active_record.rb
index 219cd30f94..348e5b94af 100644
--- a/activerecord/lib/active_record.rb
+++ b/activerecord/lib/active_record.rb
@@ -31,51 +31,47 @@ rescue LoadError
end
end
-require 'active_record/base'
-require 'active_record/named_scope'
-require 'active_record/observer'
-require 'active_record/query_cache'
-require 'active_record/validations'
-require 'active_record/callbacks'
-require 'active_record/reflection'
-require 'active_record/associations'
-require 'active_record/association_preload'
-require 'active_record/aggregations'
-require 'active_record/transactions'
-require 'active_record/timestamp'
-require 'active_record/locking/optimistic'
-require 'active_record/locking/pessimistic'
-require 'active_record/migration'
-require 'active_record/schema'
-require 'active_record/calculations'
-require 'active_record/serialization'
-require 'active_record/attribute_methods'
-require 'active_record/dirty'
-require 'active_record/dynamic_finder_match'
+module ActiveRecord
+ # TODO: Review explicit loads to see if they will automatically be handled by the initilizer.
+ def self.load_all!
+ [Base, DynamicFinderMatch, ConnectionAdapters::AbstractAdapter]
+ end
-ActiveRecord::Base.class_eval do
- extend ActiveRecord::QueryCache
- include ActiveRecord::Validations
- include ActiveRecord::Locking::Optimistic
- include ActiveRecord::Locking::Pessimistic
- include ActiveRecord::AttributeMethods
- include ActiveRecord::Dirty
- include ActiveRecord::Callbacks
- include ActiveRecord::Observing
- include ActiveRecord::Timestamp
- include ActiveRecord::Associations
- include ActiveRecord::NamedScope
- include ActiveRecord::AssociationPreload
- include ActiveRecord::Aggregations
- include ActiveRecord::Transactions
- include ActiveRecord::Reflection
- include ActiveRecord::Calculations
- include ActiveRecord::Serialization
-end
+ autoload :ActiveRecordError, 'active_record/base'
+ autoload :ConnectionNotEstablished, 'active_record/base'
+
+ autoload :Aggregations, 'active_record/aggregations'
+ autoload :AssociationPreload, 'active_record/association_preload'
+ autoload :Associations, 'active_record/associations'
+ autoload :AttributeMethods, 'active_record/attribute_methods'
+ autoload :Base, 'active_record/base'
+ autoload :Calculations, 'active_record/calculations'
+ autoload :Callbacks, 'active_record/callbacks'
+ autoload :Dirty, 'active_record/dirty'
+ autoload :DynamicFinderMatch, 'active_record/dynamic_finder_match'
+ autoload :Migration, 'active_record/migration'
+ autoload :Migrator, 'active_record/migration'
+ autoload :NamedScope, 'active_record/named_scope'
+ autoload :Observing, 'active_record/observer'
+ autoload :QueryCache, 'active_record/query_cache'
+ autoload :Reflection, 'active_record/reflection'
+ autoload :Schema, 'active_record/schema'
+ autoload :SchemaDumper, 'active_record/schema_dumper'
+ autoload :Serialization, 'active_record/serialization'
+ autoload :TestCase, 'active_record/test_case'
+ autoload :Timestamp, 'active_record/timestamp'
+ autoload :Transactions, 'active_record/transactions'
+ autoload :Validations, 'active_record/validations'
-require 'active_record/connection_adapters/abstract_adapter'
+ module Locking
+ autoload :Optimistic, 'active_record/locking/optimistic'
+ autoload :Pessimistic, 'active_record/locking/pessimistic'
+ end
-require 'active_record/schema_dumper'
+ module ConnectionAdapters
+ autoload :AbstractAdapter, 'active_record/connection_adapters/abstract_adapter'
+ end
+end
require 'active_record/i18n_interpolation_deprecation'
-I18n.load_path << File.dirname(__FILE__) + '/active_record/locale/en-US.yml'
+I18n.load_path << File.dirname(__FILE__) + '/active_record/locale/en.yml'
diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb
index 6e194ab9b4..99c3ce5e62 100644
--- a/activerecord/lib/active_record/association_preload.rb
+++ b/activerecord/lib/active_record/association_preload.rb
@@ -185,7 +185,7 @@ module ActiveRecord
associated_records = reflection.klass.find(:all, :conditions => [conditions, ids],
:include => options[:include],
- :joins => "INNER JOIN #{connection.quote_table_name options[:join_table]} as t0 ON #{reflection.klass.quoted_table_name}.#{reflection.klass.primary_key} = t0.#{reflection.association_foreign_key}",
+ :joins => "INNER JOIN #{connection.quote_table_name options[:join_table]} t0 ON #{reflection.klass.quoted_table_name}.#{reflection.klass.primary_key} = t0.#{reflection.association_foreign_key}",
:select => "#{options[:select] || table_name+'.*'}, t0.#{reflection.primary_key_name} as the_parent_record_id",
:order => options[:order])
@@ -312,7 +312,7 @@ module ActiveRecord
table_name = klass.quoted_table_name
primary_key = klass.primary_key
column_type = klass.columns.detect{|c| c.name == primary_key}.type
- ids = id_map.keys.uniq.map do |id|
+ ids = id_map.keys.map do |id|
if column_type == :integer
id.to_i
elsif column_type == :float
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index c7cb6eb966..3fbbea43ed 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1,13 +1,3 @@
-require 'active_record/associations/association_proxy'
-require 'active_record/associations/association_collection'
-require 'active_record/associations/belongs_to_association'
-require 'active_record/associations/belongs_to_polymorphic_association'
-require 'active_record/associations/has_one_association'
-require 'active_record/associations/has_many_association'
-require 'active_record/associations/has_many_through_association'
-require 'active_record/associations/has_and_belongs_to_many_association'
-require 'active_record/associations/has_one_through_association'
-
module ActiveRecord
class HasManyThroughAssociationNotFoundError < ActiveRecordError #:nodoc:
def initialize(owner_class_name, reflection)
@@ -75,6 +65,18 @@ module ActiveRecord
# See ActiveRecord::Associations::ClassMethods for documentation.
module Associations # :nodoc:
+ # These classes will be loaded when associatoins are created.
+ # So there is no need to eager load them.
+ autoload :AssociationCollection, 'active_record/associations/association_collection'
+ autoload :AssociationProxy, 'active_record/associations/association_proxy'
+ autoload :BelongsToAssociation, 'active_record/associations/belongs_to_association'
+ autoload :BelongsToPolymorphicAssociation, 'active_record/associations/belongs_to_polymorphic_association'
+ autoload :HasAndBelongsToManyAssociation, 'active_record/associations/has_and_belongs_to_many_association'
+ autoload :HasManyAssociation, 'active_record/associations/has_many_association'
+ autoload :HasManyThroughAssociation, 'active_record/associations/has_many_through_association'
+ autoload :HasOneAssociation, 'active_record/associations/has_one_association'
+ autoload :HasOneThroughAssociation, 'active_record/associations/has_one_through_association'
+
def self.included(base)
base.extend(ClassMethods)
end
@@ -722,6 +724,8 @@ module ActiveRecord
# Specify second-order associations that should be eager loaded when the collection is loaded.
# [:group]
# An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</tt> SQL-clause.
+ # [:having]
+ # Combined with +:group+ this can be used to filter the records that a <tt>GROUP BY</tt> returns. Uses the <tt>HAVING</tt> SQL-clause.
# [:limit]
# An integer determining the limit on the number of rows that should be returned.
# [:offset]
@@ -1179,6 +1183,8 @@ module ActiveRecord
# Specify second-order associations that should be eager loaded when the collection is loaded.
# [:group]
# An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</tt> SQL-clause.
+ # [:having]
+ # Combined with +:group+ this can be used to filter the records that a <tt>GROUP BY</tt> returns. Uses the <tt>HAVING</tt> SQL-clause.
# [:limit]
# An integer determining the limit on the number of rows that should be returned.
# [:offset]
@@ -1551,7 +1557,7 @@ module ActiveRecord
@@valid_keys_for_has_many_association = [
:class_name, :table_name, :foreign_key, :primary_key,
:dependent,
- :select, :conditions, :include, :order, :group, :limit, :offset,
+ :select, :conditions, :include, :order, :group, :having, :limit, :offset,
:as, :through, :source, :source_type,
:uniq,
:finder_sql, :counter_sql,
@@ -1607,9 +1613,9 @@ module ActiveRecord
mattr_accessor :valid_keys_for_has_and_belongs_to_many_association
@@valid_keys_for_has_and_belongs_to_many_association = [
:class_name, :table_name, :join_table, :foreign_key, :association_foreign_key,
- :select, :conditions, :include, :order, :group, :limit, :offset,
+ :select, :conditions, :include, :order, :group, :having, :limit, :offset,
:uniq,
- :finder_sql, :delete_sql, :insert_sql,
+ :finder_sql, :counter_sql, :delete_sql, :insert_sql,
:before_add, :after_add, :before_remove, :after_remove,
:extend, :readonly,
:validate
@@ -1656,7 +1662,7 @@ module ActiveRecord
add_conditions!(sql, options[:conditions], scope)
add_limited_ids_condition!(sql, options, join_dependency) if !using_limitable_reflections?(join_dependency.reflections) && ((scope && scope[:limit]) || options[:limit])
- add_group!(sql, options[:group], scope)
+ add_group!(sql, options[:group], options[:having], scope)
add_order!(sql, options[:order], scope)
add_limit!(sql, options, scope) if using_limitable_reflections?(join_dependency.reflections)
add_lock!(sql, options, scope)
@@ -1712,7 +1718,7 @@ module ActiveRecord
end
add_conditions!(sql, options[:conditions], scope)
- add_group!(sql, options[:group], scope)
+ add_group!(sql, options[:group], options[:having], scope)
if order && is_distinct
connection.add_order_by_for_association_limiting!(sql, :order => order)
@@ -1731,6 +1737,7 @@ module ActiveRecord
case cond
when nil then all
when Array then all << cond.first
+ when Hash then all << cond.keys
else all << cond
end
end
diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb
index d1a79df6e6..75ec4fbb2e 100644
--- a/activerecord/lib/active_record/associations/association_proxy.rb
+++ b/activerecord/lib/active_record/associations/association_proxy.rb
@@ -188,6 +188,7 @@ module ActiveRecord
def merge_options_from_reflection!(options)
options.reverse_merge!(
:group => @reflection.options[:group],
+ :having => @reflection.options[:having],
:limit => @reflection.options[:limit],
:offset => @reflection.options[:offset],
:joins => @reflection.options[:joins],
diff --git a/activerecord/lib/active_record/associations/has_one_through_association.rb b/activerecord/lib/active_record/associations/has_one_through_association.rb
index b78bd5d931..8073ebaf9f 100644
--- a/activerecord/lib/active_record/associations/has_one_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_one_through_association.rb
@@ -8,11 +8,10 @@ module ActiveRecord
current_object = @owner.send(@reflection.through_reflection.name)
if current_object
- klass.destroy(current_object)
- @owner.clear_association_cache
+ current_object.update_attributes(construct_join_attributes(new_value))
+ else
+ @owner.send(@reflection.through_reflection.name, klass.send(:create, construct_join_attributes(new_value)))
end
-
- @owner.send(@reflection.through_reflection.name, klass.send(:create, construct_join_attributes(new_value)))
end
private
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index a36a137f0d..8f8ed241d5 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -495,6 +495,10 @@ module ActiveRecord #:nodoc:
superclass_delegating_accessor :store_full_sti_class
self.store_full_sti_class = false
+ # Stores the default scope for the class
+ class_inheritable_accessor :default_scoping, :instance_writer => false
+ self.default_scoping = []
+
class << self # Class methods
# Find operates with four different retrieval approaches:
#
@@ -517,6 +521,7 @@ module ActiveRecord #:nodoc:
# * <tt>:conditions</tt> - An SQL fragment like "administrator = 1", <tt>[ "user_name = ?", username ]</tt>, or <tt>["user_name = :user_name", { :user_name => user_name }]</tt>. See conditions in the intro.
# * <tt>:order</tt> - An SQL fragment like "created_at DESC, name".
# * <tt>:group</tt> - An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</tt> SQL-clause.
+ # * <tt>:having</tt> - Combined with +:group+ this can be used to filter the records that a <tt>GROUP BY</tt> returns. Uses the <tt>HAVING</tt> SQL-clause.
# * <tt>:limit</tt> - An integer determining the limit on the number of rows that should be returned.
# * <tt>:offset</tt> - An integer determining the offset from where the rows should be fetched. So at 5, it would skip rows 0 through 4.
# * <tt>:joins</tt> - Either an SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id" (rarely needed)
@@ -1612,15 +1617,23 @@ module ActiveRecord #:nodoc:
end
end
+ def default_select(qualified)
+ if qualified
+ quoted_table_name + '.*'
+ else
+ '*'
+ end
+ end
+
def construct_finder_sql(options)
scope = scope(:find)
- sql = "SELECT #{options[:select] || (scope && scope[:select]) || ((options[:joins] || (scope && scope[:joins])) && quoted_table_name + '.*') || '*'} "
+ sql = "SELECT #{options[:select] || (scope && scope[:select]) || default_select(options[:joins] || (scope && scope[:joins]))} "
sql << "FROM #{(scope && scope[:from]) || options[:from] || quoted_table_name} "
add_joins!(sql, options[:joins], scope)
add_conditions!(sql, options[:conditions], scope)
- add_group!(sql, options[:group], scope)
+ add_group!(sql, options[:group], options[:having], scope)
add_order!(sql, options[:order], scope)
add_limit!(sql, options, scope)
add_lock!(sql, options, scope)
@@ -1676,13 +1689,15 @@ module ActiveRecord #:nodoc:
end
end
- def add_group!(sql, group, scope = :auto)
+ def add_group!(sql, group, having, scope = :auto)
if group
sql << " GROUP BY #{group}"
+ sql << " HAVING #{having}" if having
else
scope = scope(:find) if :auto == scope
if scope && (scoped_group = scope[:group])
sql << " GROUP BY #{scoped_group}"
+ sql << " HAVING #{scoped_having}" if (scoped_having = scope[:having])
end
end
end
@@ -2008,6 +2023,16 @@ module ActiveRecord #:nodoc:
@@subclasses[self] + extra = @@subclasses[self].inject([]) {|list, subclass| list + subclass.subclasses }
end
+ # Sets the default options for the model. The format of the
+ # <tt>method_scoping</tt> argument is the same as in with_scope.
+ #
+ # class Person < ActiveRecord::Base
+ # default_scope :find => { :order => 'last_name, first_name' }
+ # end
+ def default_scope(options = {})
+ self.default_scoping << { :find => options, :create => (options.is_a?(Hash) && options.has_key?(:conditions)) ? options[:conditions] : {} }
+ end
+
# Test whether the given method and optional key are scoped.
def scoped?(method, key = nil) #:nodoc:
if current_scoped_methods && (scope = current_scoped_methods[method])
@@ -2023,8 +2048,7 @@ module ActiveRecord #:nodoc:
end
def scoped_methods #:nodoc:
- scoped_methods = (Thread.current[:scoped_methods] ||= {})
- scoped_methods[self] ||= []
+ Thread.current[:"#{self}_scoped_methods"] ||= self.default_scoping.dup
end
def current_scoped_methods #:nodoc:
@@ -2238,7 +2262,7 @@ module ActiveRecord #:nodoc:
end
VALID_FIND_OPTIONS = [ :conditions, :include, :joins, :limit, :offset,
- :order, :select, :readonly, :group, :from, :lock ]
+ :order, :select, :readonly, :group, :having, :from, :lock ]
def validate_find_options(options) #:nodoc:
options.assert_valid_keys(VALID_FIND_OPTIONS)
@@ -2301,7 +2325,7 @@ module ActiveRecord #:nodoc:
# construct an URI with the user object's 'id' in it:
#
# user = User.find_by_name('Phusion')
- # user_path(path) # => "/users/1"
+ # user_path(user) # => "/users/1"
#
# You can override +to_param+ in your model to make +users_path+ construct
# an URI using the user's name instead of the user's id:
@@ -2313,7 +2337,7 @@ module ActiveRecord #:nodoc:
# end
#
# user = User.find_by_name('Phusion')
- # user_path(path) # => "/users/Phusion"
+ # user_path(user) # => "/users/Phusion"
def to_param
# We can't use alias_method here, because method 'id' optimizes itself on the fly.
(id = self.id) ? id.to_s : nil # Be sure to stringify the id for routes
@@ -2957,4 +2981,18 @@ module ActiveRecord #:nodoc:
value
end
end
+
+ Base.class_eval do
+ extend QueryCache
+ include Validations
+ include Locking::Optimistic, Locking::Pessimistic
+ include AttributeMethods
+ include Dirty
+ include Callbacks, Observing, Timestamp
+ include Associations, AssociationPreload, NamedScope
+ include Aggregations, Transactions, Reflection, Calculations, Serialization
+ end
end
+
+# TODO: Remove this and make it work with LAZY flag
+require 'active_record/connection_adapters/abstract_adapter'
diff --git a/activerecord/lib/active_record/calculations.rb b/activerecord/lib/active_record/calculations.rb
index 5e33cf1bd4..65512d534a 100644
--- a/activerecord/lib/active_record/calculations.rb
+++ b/activerecord/lib/active_record/calculations.rb
@@ -286,7 +286,7 @@ module ActiveRecord
case operation
when 'count' then value.to_i
when 'sum' then type_cast_using_column(value || '0', column)
- when 'avg' then value && value.to_d
+ when 'avg' then value && (value.is_a?(Fixnum) ? value.to_f : value).to_d
else type_cast_using_column(value, column)
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
index 432c341e6c..901b17124c 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -65,15 +65,23 @@ module ActiveRecord
# The default ConnectionPool maximum size is 5.
def initialize(spec)
@spec = spec
+
# The cache of reserved connections mapped to threads
@reserved_connections = {}
+
# The mutex used to synchronize pool access
@connection_mutex = Monitor.new
@queue = @connection_mutex.new_cond
- # default 5 second timeout
- @timeout = spec.config[:wait_timeout] || 5
+
+ # default 5 second timeout unless on ruby 1.9
+ @timeout =
+ if RUBY_VERSION < '1.9'
+ spec.config[:wait_timeout] || 5
+ end
+
# default max pool size to 5
@size = (spec.config[:pool] && spec.config[:pool].to_i) || 5
+
@connections = []
@checked_out = []
end
@@ -187,7 +195,7 @@ module ActiveRecord
# try looting dead threads
clear_stale_cached_connections!
if @size == @checked_out.size
- raise ConnectionTimeoutError, "could not obtain a database connection within #{@timeout} seconds. The pool size is currently #{@size}, perhaps you need to increase it?"
+ raise ConnectionTimeoutError, "could not obtain a database connection#{" within #{@timeout} seconds" if @timeout}. The max pool size is currently #{@size}; consider increasing it."
end
end
end
@@ -292,10 +300,7 @@ module ActiveRecord
# and also returns connections to the pool cached by threads that are no
# longer alive.
def clear_active_connections!
- @connection_pools.each_value do |pool|
- pool.release_connection
- pool.clear_stale_cached_connections!
- end
+ @connection_pools.each_value {|pool| pool.release_connection }
end
# Clears the cache which maps classes
@@ -324,7 +329,8 @@ module ActiveRecord
# Returns true if a connection that's accessible to this class has
# already been opened.
def connected?(klass)
- retrieve_connection_pool(klass).connected?
+ conn = retrieve_connection_pool(klass)
+ conn ? conn.connected? : false
end
# Remove the connection for this class. This will close the active
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 a9a63e5a9f..cecbc6b3ac 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -31,13 +31,13 @@ module ActiveRecord
# Returns an array of arrays containing the field values.
# Order is the same as that returned by +columns+.
def select_rows(sql, name = nil)
- raise NotImplementedError, "select_rows is an abstract method"
end
+ undef_method :select_rows
# Executes the SQL statement in the context of this connection.
- def execute(sql, name = nil)
- raise NotImplementedError, "execute is an abstract method"
+ def execute(sql, name = nil, skip_logging = false)
end
+ undef_method :execute
# Returns the last auto-generated ID from the affected table.
def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
@@ -246,8 +246,8 @@ module ActiveRecord
# Returns an array of record hashes with the column names as keys and
# column values as values.
def select(sql, name = nil)
- raise NotImplementedError, "select is an abstract method"
end
+ undef_method :select
# Returns the last auto-generated ID from the affected table.
def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index 81260eeecc..b26185580c 100755
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -3,6 +3,7 @@ require 'date'
require 'bigdecimal'
require 'bigdecimal/util'
+# TODO: Autoload these files
require 'active_record/connection_adapters/abstract/schema_definitions'
require 'active_record/connection_adapters/abstract/schema_statements'
require 'active_record/connection_adapters/abstract/database_statements'
@@ -31,7 +32,7 @@ module ActiveRecord
include QueryCache
include ActiveSupport::Callbacks
define_callbacks :checkout, :checkin
- checkout :reset!
+
@@row_even = true
def initialize(connection, logger = nil) #:nodoc:
@@ -131,9 +132,8 @@ module ActiveRecord
end
# Returns true if its safe to reload the connection between requests for development mode.
- # This is not the case for Ruby/MySQL and it's not necessary for any adapters except SQLite.
def requires_reloading?
- false
+ true
end
# Checks whether the connection to the database is still active (i.e. not stale).
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index 3d8b0e40a9..039d5a4e8e 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -1,6 +1,7 @@
require 'erb'
require 'yaml'
require 'csv'
+require 'active_support/dependencies'
require 'active_support/test_case'
if RUBY_VERSION < '1.9'
@@ -813,188 +814,192 @@ class Fixture #:nodoc:
end
end
-module Test #:nodoc:
- module Unit #:nodoc:
- class TestCase #:nodoc:
- setup :setup_fixtures
- teardown :teardown_fixtures
-
- superclass_delegating_accessor :fixture_path
- superclass_delegating_accessor :fixture_table_names
- superclass_delegating_accessor :fixture_class_names
- superclass_delegating_accessor :use_transactional_fixtures
- superclass_delegating_accessor :use_instantiated_fixtures # true, false, or :no_instances
- superclass_delegating_accessor :pre_loaded_fixtures
-
- self.fixture_table_names = []
- self.use_transactional_fixtures = false
- self.use_instantiated_fixtures = true
- self.pre_loaded_fixtures = false
-
- @@already_loaded_fixtures = {}
- self.fixture_class_names = {}
-
- class << self
- def set_fixture_class(class_names = {})
- self.fixture_class_names = self.fixture_class_names.merge(class_names)
- end
+module ActiveRecord
+ module TestFixtures
+ def self.included(base)
+ base.class_eval do
+ setup :setup_fixtures
+ teardown :teardown_fixtures
+
+ superclass_delegating_accessor :fixture_path
+ superclass_delegating_accessor :fixture_table_names
+ superclass_delegating_accessor :fixture_class_names
+ superclass_delegating_accessor :use_transactional_fixtures
+ superclass_delegating_accessor :use_instantiated_fixtures # true, false, or :no_instances
+ superclass_delegating_accessor :pre_loaded_fixtures
+
+ self.fixture_table_names = []
+ self.use_transactional_fixtures = false
+ self.use_instantiated_fixtures = true
+ self.pre_loaded_fixtures = false
+
+ self.fixture_class_names = {}
+ end
- def fixtures(*table_names)
- if table_names.first == :all
- table_names = Dir["#{fixture_path}/*.yml"] + Dir["#{fixture_path}/*.csv"]
- table_names.map! { |f| File.basename(f).split('.')[0..-2].join('.') }
- else
- table_names = table_names.flatten.map { |n| n.to_s }
- end
+ base.extend ClassMethods
+ end
+
+ module ClassMethods
+ def set_fixture_class(class_names = {})
+ self.fixture_class_names = self.fixture_class_names.merge(class_names)
+ end
- self.fixture_table_names |= table_names
- require_fixture_classes(table_names)
- setup_fixture_accessors(table_names)
+ def fixtures(*table_names)
+ if table_names.first == :all
+ table_names = Dir["#{fixture_path}/*.yml"] + Dir["#{fixture_path}/*.csv"]
+ table_names.map! { |f| File.basename(f).split('.')[0..-2].join('.') }
+ else
+ table_names = table_names.flatten.map { |n| n.to_s }
end
- def try_to_load_dependency(file_name)
- require_dependency file_name
- rescue LoadError => e
- # Let's hope the developer has included it himself
+ self.fixture_table_names |= table_names
+ require_fixture_classes(table_names)
+ setup_fixture_accessors(table_names)
+ end
+
+ def try_to_load_dependency(file_name)
+ require_dependency file_name
+ rescue LoadError => e
+ # Let's hope the developer has included it himself
- # Let's warn in case this is a subdependency, otherwise
- # subdependency error messages are totally cryptic
- if ActiveRecord::Base.logger
- ActiveRecord::Base.logger.warn("Unable to load #{file_name}, underlying cause #{e.message} \n\n #{e.backtrace.join("\n")}")
- end
+ # Let's warn in case this is a subdependency, otherwise
+ # subdependency error messages are totally cryptic
+ if ActiveRecord::Base.logger
+ ActiveRecord::Base.logger.warn("Unable to load #{file_name}, underlying cause #{e.message} \n\n #{e.backtrace.join("\n")}")
end
+ end
- def require_fixture_classes(table_names = nil)
- (table_names || fixture_table_names).each do |table_name|
- file_name = table_name.to_s
- file_name = file_name.singularize if ActiveRecord::Base.pluralize_table_names
- try_to_load_dependency(file_name)
- end
+ def require_fixture_classes(table_names = nil)
+ (table_names || fixture_table_names).each do |table_name|
+ file_name = table_name.to_s
+ file_name = file_name.singularize if ActiveRecord::Base.pluralize_table_names
+ try_to_load_dependency(file_name)
end
+ end
- def setup_fixture_accessors(table_names = nil)
- table_names = [table_names] if table_names && !table_names.respond_to?(:each)
- (table_names || fixture_table_names).each do |table_name|
- table_name = table_name.to_s.tr('.', '_')
+ def setup_fixture_accessors(table_names = nil)
+ table_names = [table_names] if table_names && !table_names.respond_to?(:each)
+ (table_names || fixture_table_names).each do |table_name|
+ table_name = table_name.to_s.tr('.', '_')
- define_method(table_name) do |*fixtures|
- force_reload = fixtures.pop if fixtures.last == true || fixtures.last == :reload
+ define_method(table_name) do |*fixtures|
+ force_reload = fixtures.pop if fixtures.last == true || fixtures.last == :reload
- @fixture_cache[table_name] ||= {}
+ @fixture_cache[table_name] ||= {}
- instances = fixtures.map do |fixture|
- @fixture_cache[table_name].delete(fixture) if force_reload
+ instances = fixtures.map do |fixture|
+ @fixture_cache[table_name].delete(fixture) if force_reload
- if @loaded_fixtures[table_name][fixture.to_s]
- @fixture_cache[table_name][fixture] ||= @loaded_fixtures[table_name][fixture.to_s].find
- else
- raise StandardError, "No fixture with name '#{fixture}' found for table '#{table_name}'"
- end
+ if @loaded_fixtures[table_name][fixture.to_s]
+ @fixture_cache[table_name][fixture] ||= @loaded_fixtures[table_name][fixture.to_s].find
+ else
+ raise StandardError, "No fixture with name '#{fixture}' found for table '#{table_name}'"
end
-
- instances.size == 1 ? instances.first : instances
end
- end
- end
- def uses_transaction(*methods)
- @uses_transaction = [] unless defined?(@uses_transaction)
- @uses_transaction.concat methods.map(&:to_s)
+ instances.size == 1 ? instances.first : instances
+ end
end
+ end
- def uses_transaction?(method)
- @uses_transaction = [] unless defined?(@uses_transaction)
- @uses_transaction.include?(method.to_s)
- end
+ def uses_transaction(*methods)
+ @uses_transaction = [] unless defined?(@uses_transaction)
+ @uses_transaction.concat methods.map(&:to_s)
end
- def use_transactional_fixtures?
- use_transactional_fixtures &&
- !self.class.uses_transaction?(method_name)
+ def uses_transaction?(method)
+ @uses_transaction = [] unless defined?(@uses_transaction)
+ @uses_transaction.include?(method.to_s)
end
+ end
- def setup_fixtures
- return unless defined?(ActiveRecord) && !ActiveRecord::Base.configurations.blank?
+ def run_in_transaction?
+ use_transactional_fixtures &&
+ !self.class.uses_transaction?(method_name)
+ end
- if pre_loaded_fixtures && !use_transactional_fixtures
- raise RuntimeError, 'pre_loaded_fixtures requires use_transactional_fixtures'
- end
+ def setup_fixtures
+ return unless defined?(ActiveRecord) && !ActiveRecord::Base.configurations.blank?
- @fixture_cache = {}
+ if pre_loaded_fixtures && !use_transactional_fixtures
+ raise RuntimeError, 'pre_loaded_fixtures requires use_transactional_fixtures'
+ end
- # Load fixtures once and begin transaction.
- if use_transactional_fixtures?
- if @@already_loaded_fixtures[self.class]
- @loaded_fixtures = @@already_loaded_fixtures[self.class]
- else
- load_fixtures
- @@already_loaded_fixtures[self.class] = @loaded_fixtures
- end
- ActiveRecord::Base.connection.increment_open_transactions
- ActiveRecord::Base.connection.begin_db_transaction
- ActiveRecord::Base.connection.transactional_fixtures = true
- # Load fixtures for every test.
+ @fixture_cache = {}
+ @@already_loaded_fixtures ||= {}
+
+ # Load fixtures once and begin transaction.
+ if run_in_transaction?
+ if @@already_loaded_fixtures[self.class]
+ @loaded_fixtures = @@already_loaded_fixtures[self.class]
else
- Fixtures.reset_cache
- @@already_loaded_fixtures[self.class] = nil
load_fixtures
+ @@already_loaded_fixtures[self.class] = @loaded_fixtures
end
-
- # Instantiate fixtures for every test if requested.
- instantiate_fixtures if use_instantiated_fixtures
+ ActiveRecord::Base.connection.increment_open_transactions
+ ActiveRecord::Base.connection.begin_db_transaction
+ ActiveRecord::Base.connection.transactional_fixtures = true
+ # Load fixtures for every test.
+ else
+ Fixtures.reset_cache
+ @@already_loaded_fixtures[self.class] = nil
+ load_fixtures
end
- def teardown_fixtures
- return unless defined?(ActiveRecord) && !ActiveRecord::Base.configurations.blank?
+ # Instantiate fixtures for every test if requested.
+ instantiate_fixtures if use_instantiated_fixtures
+ end
+
+ def teardown_fixtures
+ return unless defined?(ActiveRecord) && !ActiveRecord::Base.configurations.blank?
- unless use_transactional_fixtures?
- Fixtures.reset_cache
- end
+ unless run_in_transaction?
+ Fixtures.reset_cache
+ end
- # Rollback changes if a transaction is active.
- if use_transactional_fixtures? && ActiveRecord::Base.connection.open_transactions != 0
- ActiveRecord::Base.connection.rollback_db_transaction
- ActiveRecord::Base.connection.decrement_open_transactions
- ActiveRecord::Base.connection.transactional_fixtures = false
- end
- ActiveRecord::Base.clear_active_connections!
+ # Rollback changes if a transaction is active.
+ if run_in_transaction? && ActiveRecord::Base.connection.open_transactions != 0
+ ActiveRecord::Base.connection.rollback_db_transaction
+ ActiveRecord::Base.connection.decrement_open_transactions
+ ActiveRecord::Base.connection.transactional_fixtures = false
end
+ ActiveRecord::Base.clear_active_connections!
+ end
- private
- def load_fixtures
- @loaded_fixtures = {}
- fixtures = Fixtures.create_fixtures(fixture_path, fixture_table_names, fixture_class_names)
- unless fixtures.nil?
- if fixtures.instance_of?(Fixtures)
- @loaded_fixtures[fixtures.name] = fixtures
- else
- fixtures.each { |f| @loaded_fixtures[f.name] = f }
- end
+ private
+ def load_fixtures
+ @loaded_fixtures = {}
+ fixtures = Fixtures.create_fixtures(fixture_path, fixture_table_names, fixture_class_names)
+ unless fixtures.nil?
+ if fixtures.instance_of?(Fixtures)
+ @loaded_fixtures[fixtures.name] = fixtures
+ else
+ fixtures.each { |f| @loaded_fixtures[f.name] = f }
end
end
+ end
- # for pre_loaded_fixtures, only require the classes once. huge speed improvement
- @@required_fixture_classes = false
+ # for pre_loaded_fixtures, only require the classes once. huge speed improvement
+ @@required_fixture_classes = false
- def instantiate_fixtures
- if pre_loaded_fixtures
- raise RuntimeError, 'Load fixtures before instantiating them.' if Fixtures.all_loaded_fixtures.empty?
- unless @@required_fixture_classes
- self.class.require_fixture_classes Fixtures.all_loaded_fixtures.keys
- @@required_fixture_classes = true
- end
- Fixtures.instantiate_all_loaded_fixtures(self, load_instances?)
- else
- raise RuntimeError, 'Load fixtures before instantiating them.' if @loaded_fixtures.nil?
- @loaded_fixtures.each do |table_name, fixtures|
- Fixtures.instantiate_fixtures(self, table_name, fixtures, load_instances?)
- end
+ def instantiate_fixtures
+ if pre_loaded_fixtures
+ raise RuntimeError, 'Load fixtures before instantiating them.' if Fixtures.all_loaded_fixtures.empty?
+ unless @@required_fixture_classes
+ self.class.require_fixture_classes Fixtures.all_loaded_fixtures.keys
+ @@required_fixture_classes = true
+ end
+ Fixtures.instantiate_all_loaded_fixtures(self, load_instances?)
+ else
+ raise RuntimeError, 'Load fixtures before instantiating them.' if @loaded_fixtures.nil?
+ @loaded_fixtures.each do |table_name, fixtures|
+ Fixtures.instantiate_fixtures(self, table_name, fixtures, load_instances?)
end
end
+ end
- def load_instances?
- use_instantiated_fixtures != :no_instances
- end
- end
+ def load_instances?
+ use_instantiated_fixtures != :no_instances
+ end
end
end
diff --git a/activerecord/lib/active_record/locale/en-US.yml b/activerecord/lib/active_record/locale/en.yml
index 421f0ebd60..7e205435f7 100644
--- a/activerecord/lib/active_record/locale/en-US.yml
+++ b/activerecord/lib/active_record/locale/en.yml
@@ -1,4 +1,4 @@
-en-US:
+en:
activerecord:
errors:
# The values :model, :attribute and :value are always available for interpolation
diff --git a/activerecord/lib/active_record/serialization.rb b/activerecord/lib/active_record/serialization.rb
index 332cda1e16..870b4b2dd4 100644
--- a/activerecord/lib/active_record/serialization.rb
+++ b/activerecord/lib/active_record/serialization.rb
@@ -1,3 +1,5 @@
+require 'active_support/json'
+
module ActiveRecord #:nodoc:
module Serialization
class Serializer #:nodoc:
@@ -95,4 +97,4 @@ module ActiveRecord #:nodoc:
end
require 'active_record/serializers/xml_serializer'
-require 'active_record/serializers/json_serializer' \ No newline at end of file
+require 'active_record/serializers/json_serializer'
diff --git a/activerecord/lib/active_record/test_case.rb b/activerecord/lib/active_record/test_case.rb
index eabf06fc3b..149b93203e 100644
--- a/activerecord/lib/active_record/test_case.rb
+++ b/activerecord/lib/active_record/test_case.rb
@@ -1,21 +1,11 @@
require "active_support/test_case"
-module ActiveRecord
+module ActiveRecord
class TestCase < ActiveSupport::TestCase #:nodoc:
- self.fixture_path = FIXTURES_ROOT
- self.use_instantiated_fixtures = false
- self.use_transactional_fixtures = true
-
- def create_fixtures(*table_names, &block)
- Fixtures.create_fixtures(FIXTURES_ROOT, table_names, {}, &block)
- end
-
def assert_date_from_db(expected, actual, message = nil)
- # SQL Server doesn't have a separate column type just for dates,
+ # SybaseAdapter doesn't have a separate column type just for dates,
# so the time is in the string and incorrectly formatted
- if current_adapter?(:SQLServerAdapter)
- assert_equal expected.strftime("%Y/%m/%d 00:00:00"), actual.strftime("%Y/%m/%d 00:00:00")
- elsif current_adapter?(:SybaseAdapter)
+ if current_adapter?(:SybaseAdapter)
assert_equal expected.to_s, actual.to_date.to_s, message
else
assert_equal expected.to_s, actual.to_s, message
diff --git a/activerecord/lib/active_record/version.rb b/activerecord/lib/active_record/version.rb
index 2479b75789..6ac4bdc905 100644
--- a/activerecord/lib/active_record/version.rb
+++ b/activerecord/lib/active_record/version.rb
@@ -1,7 +1,7 @@
module ActiveRecord
module VERSION #:nodoc:
MAJOR = 2
- MINOR = 2
+ MINOR = 3
TINY = 0
STRING = [MAJOR, MINOR, TINY].join('.')
diff --git a/activerecord/test/cases/adapter_test_sqlserver.rb b/activerecord/test/cases/adapter_test_sqlserver.rb
deleted file mode 100644
index ea270fb7ee..0000000000
--- a/activerecord/test/cases/adapter_test_sqlserver.rb
+++ /dev/null
@@ -1,95 +0,0 @@
-require "cases/helper"
-require 'models/default'
-require 'models/post'
-require 'models/task'
-
-class SqlServerAdapterTest < ActiveRecord::TestCase
- class TableWithRealColumn < ActiveRecord::Base; end
-
- fixtures :posts, :tasks
-
- def setup
- @connection = ActiveRecord::Base.connection
- end
-
- def teardown
- @connection.execute("SET LANGUAGE us_english") rescue nil
- end
-
- def test_real_column_has_float_type
- assert_equal :float, TableWithRealColumn.columns_hash["real_number"].type
- end
-
- # SQL Server 2000 has a bug where some unambiguous date formats are not
- # correctly identified if the session language is set to german
- def test_date_insertion_when_language_is_german
- @connection.execute("SET LANGUAGE deutsch")
-
- assert_nothing_raised do
- Task.create(:starting => Time.utc(2000, 1, 31, 5, 42, 0), :ending => Date.new(2006, 12, 31))
- end
- end
-
- def test_indexes_with_descending_order
- # Make sure we have an index with descending order
- @connection.execute "CREATE INDEX idx_credit_limit ON accounts (credit_limit DESC)" rescue nil
- assert_equal ["credit_limit"], @connection.indexes('accounts').first.columns
- ensure
- @connection.execute "DROP INDEX accounts.idx_credit_limit"
- end
-
- def test_execute_without_block_closes_statement
- assert_all_statements_used_are_closed do
- @connection.execute("SELECT 1")
- end
- end
-
- def test_execute_with_block_closes_statement
- assert_all_statements_used_are_closed do
- @connection.execute("SELECT 1") do |sth|
- assert !sth.finished?, "Statement should still be alive within block"
- end
- end
- end
-
- def test_insert_with_identity_closes_statement
- assert_all_statements_used_are_closed do
- @connection.insert("INSERT INTO accounts ([id], [firm_id],[credit_limit]) values (999, 1, 50)")
- end
- end
-
- def test_insert_without_identity_closes_statement
- assert_all_statements_used_are_closed do
- @connection.insert("INSERT INTO accounts ([firm_id],[credit_limit]) values (1, 50)")
- end
- end
-
- def test_active_closes_statement
- assert_all_statements_used_are_closed do
- @connection.active?
- end
- end
-
- def assert_all_statements_used_are_closed(&block)
- existing_handles = []
- ObjectSpace.each_object(DBI::StatementHandle) {|handle| existing_handles << handle}
- GC.disable
-
- yield
-
- used_handles = []
- ObjectSpace.each_object(DBI::StatementHandle) {|handle| used_handles << handle unless existing_handles.include? handle}
-
- assert_block "No statements were used within given block" do
- used_handles.size > 0
- end
-
- ObjectSpace.each_object(DBI::StatementHandle) do |handle|
- assert_block "Statement should have been closed within given block" do
- handle.finished?
- end
- end
- ensure
- GC.enable
- end
-end
diff --git a/activerecord/test/cases/ar_schema_test.rb b/activerecord/test/cases/ar_schema_test.rb
index 431dc7a141..4c1589d965 100644
--- a/activerecord/test/cases/ar_schema_test.rb
+++ b/activerecord/test/cases/ar_schema_test.rb
@@ -1,5 +1,4 @@
require "cases/helper"
-require 'active_record/schema'
if ActiveRecord::Base.connection.supports_migrations?
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index 5f43975d5a..3c8408d14b 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -385,12 +385,28 @@ class EagerAssociationTest < ActiveRecord::TestCase
assert_equal count, posts.size
end
- def test_eager_with_has_many_and_limit_ond_high_offset
+ def test_eager_with_has_many_and_limit_and_high_offset
posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10, :conditions => [ "authors.name = ?", 'David' ])
assert_equal 0, posts.size
end
- def test_count_eager_with_has_many_and_limit_ond_high_offset
+ def test_eager_with_has_many_and_limit_and_high_offset_and_multiple_array_conditions
+ assert_queries(1) do
+ posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10,
+ :conditions => [ "authors.name = ? and comments.body = ?", 'David', 'go crazy' ])
+ assert_equal 0, posts.size
+ end
+ end
+
+ def test_eager_with_has_many_and_limit_and_high_offset_and_multiple_hash_conditions
+ assert_queries(1) do
+ posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10,
+ :conditions => { 'authors.name' => 'David', 'comments.body' => 'go crazy' })
+ assert_equal 0, posts.size
+ end
+ end
+
+ def test_count_eager_with_has_many_and_limit_and_high_offset
posts = Post.count(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10, :conditions => [ "authors.name = ?", 'David' ])
assert_equal 0, posts
end
@@ -667,7 +683,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
end
def test_count_with_include
- if current_adapter?(:SQLServerAdapter, :SybaseAdapter)
+ if current_adapter?(:SybaseAdapter)
assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "len(comments.body) > 15")
elsif current_adapter?(:OpenBaseAdapter)
assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "length(FETCHBLOB(comments.body)) > 15")
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 2949f1d304..2f08e09d43 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
@@ -68,6 +68,16 @@ class DeveloperWithSymbolsForKeys < ActiveRecord::Base
:foreign_key => "developer_id"
end
+class DeveloperWithCounterSQL < ActiveRecord::Base
+ set_table_name 'developers'
+ has_and_belongs_to_many :projects,
+ :class_name => "DeveloperWithCounterSQL",
+ :join_table => "developers_projects",
+ :association_foreign_key => "project_id",
+ :foreign_key => "developer_id",
+ :counter_sql => 'SELECT COUNT(*) AS count_all FROM projects INNER JOIN developers_projects ON projects.id = developers_projects.project_id WHERE developers_projects.developer_id =#{id}'
+end
+
class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects,
:parrots, :pirates, :treasures, :price_estimates, :tags, :taggings
@@ -648,6 +658,11 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
assert_equal 1, categories(:technology).posts_gruoped_by_title.size
end
+ def test_find_scoped_grouped_having
+ assert_equal 2, projects(:active_record).well_payed_salary_groups.size
+ assert projects(:active_record).well_payed_salary_groups.all? { |g| g.salary > 10000 }
+ end
+
def test_get_ids
assert_equal projects(:active_record, :action_controller).map(&:id).sort, developers(:david).project_ids.sort
assert_equal [projects(:active_record).id], developers(:jamis).project_ids
@@ -739,6 +754,19 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
assert_nothing_raised { david.projects.count(:all, :conditions => '1=1') }
end
+ def test_count
+ david = Developer.find(1)
+ assert_equal 2, david.projects.count
+ end
+
+ def test_count_with_counter_sql
+ developer = DeveloperWithCounterSQL.create(:name => 'tekin')
+ developer.project_ids = [projects(:active_record).id]
+ developer.save
+ developer.reload
+ assert_equal 1, developer.projects.count
+ end
+
uses_mocha 'mocking Post.transaction' do
def test_association_proxy_transaction_method_starts_transaction_in_association_class
Post.expects(:transaction)
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index 59784e1bcb..816ceb6855 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -255,6 +255,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal 2, companies(:first_firm).clients_grouped_by_name.length
end
+ def test_find_scoped_grouped_having
+ assert_equal 1, authors(:david).popular_grouped_posts.length
+ assert_equal 0, authors(:mary).popular_grouped_posts.length
+ end
+
def test_adding
force_signal37_to_load_all_clients_of_firm
natural = Client.new("name" => "Natural Company")
diff --git a/activerecord/test/cases/associations/has_one_through_associations_test.rb b/activerecord/test/cases/associations/has_one_through_associations_test.rb
index ff4021fe02..7d418de965 100644
--- a/activerecord/test/cases/associations/has_one_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_through_associations_test.rb
@@ -3,9 +3,11 @@ require 'models/club'
require 'models/member'
require 'models/membership'
require 'models/sponsor'
+require 'models/organization'
+require 'models/member_detail'
class HasOneThroughAssociationsTest < ActiveRecord::TestCase
- fixtures :members, :clubs, :memberships, :sponsors
+ fixtures :members, :clubs, :memberships, :sponsors, :organizations
def setup
@member = members(:groucho)
@@ -120,4 +122,40 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase
clubs(:moustache_club).send(:private_method)
@member.club.send(:private_method)
end
+
+ def test_assigning_to_has_one_through_preserves_decorated_join_record
+ @organization = organizations(:nsa)
+ assert_difference 'MemberDetail.count', 1 do
+ @member_detail = MemberDetail.new(:extra_data => 'Extra')
+ @member.member_detail = @member_detail
+ @member.organization = @organization
+ end
+ assert_equal @organization, @member.organization
+ assert @organization.members.include?(@member)
+ assert_equal 'Extra', @member.member_detail.extra_data
+ end
+
+ def test_reassigning_has_one_through
+ @organization = organizations(:nsa)
+ @new_organization = organizations(:discordians)
+
+ assert_difference 'MemberDetail.count', 1 do
+ @member_detail = MemberDetail.new(:extra_data => 'Extra')
+ @member.member_detail = @member_detail
+ @member.organization = @organization
+ end
+ assert_equal @organization, @member.organization
+ assert_equal 'Extra', @member.member_detail.extra_data
+ assert @organization.members.include?(@member)
+ assert !@new_organization.members.include?(@member)
+
+ assert_no_difference 'MemberDetail.count' do
+ @member.organization = @new_organization
+ end
+ assert_equal @new_organization, @member.organization
+ assert_equal 'Extra', @member.member_detail.extra_data
+ assert !@organization.members.include?(@member)
+ assert @new_organization.members.include?(@member)
+ end
+
end
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index da9f2742d8..5f54931d00 100755
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -428,9 +428,6 @@ class BasicsTest < ActiveRecord::TestCase
end
def test_preserving_date_objects
- # SQL Server doesn't have a separate column type just for dates, so all are returned as time
- return true if current_adapter?(:SQLServerAdapter)
-
if current_adapter?(:SybaseAdapter, :OracleAdapter)
# Sybase ctlib does not (yet?) support the date type; use datetime instead.
# Oracle treats all dates/times as Time.
@@ -777,8 +774,8 @@ class BasicsTest < ActiveRecord::TestCase
end
end
- # Oracle, SQLServer, and Sybase do not have a TIME datatype.
- unless current_adapter?(:SQLServerAdapter, :OracleAdapter, :SybaseAdapter)
+ # Oracle, and Sybase do not have a TIME datatype.
+ unless current_adapter?(:OracleAdapter, :SybaseAdapter)
def test_utc_as_time_zone
Topic.default_timezone = :utc
attributes = { "bonus_time" => "5:42:00AM" }
@@ -1157,8 +1154,8 @@ class BasicsTest < ActiveRecord::TestCase
end
def test_attributes_on_dummy_time
- # Oracle, SQL Server, and Sybase do not have a TIME datatype.
- return true if current_adapter?(:SQLServerAdapter, :OracleAdapter, :SybaseAdapter)
+ # Oracle, and Sybase do not have a TIME datatype.
+ return true if current_adapter?(:OracleAdapter, :SybaseAdapter)
attributes = {
"bonus_time" => "5:42:00AM"
@@ -1874,7 +1871,7 @@ class BasicsTest < ActiveRecord::TestCase
assert_equal "integer", xml.elements["//parent-id"].attributes['type']
assert_equal "true", xml.elements["//parent-id"].attributes['nil']
- if current_adapter?(:SybaseAdapter, :SQLServerAdapter, :OracleAdapter)
+ if current_adapter?(:SybaseAdapter, :OracleAdapter)
assert_equal last_read_in_current_timezone, xml.elements["//last-read"].text
assert_equal "datetime" , xml.elements["//last-read"].attributes['type']
else
diff --git a/activerecord/test/cases/binary_test.rb b/activerecord/test/cases/binary_test.rb
index 7131532c05..8545ba97cc 100644
--- a/activerecord/test/cases/binary_test.rb
+++ b/activerecord/test/cases/binary_test.rb
@@ -1,13 +1,9 @@
require "cases/helper"
# Without using prepared statements, it makes no sense to test
-# BLOB data with SQL Server, because the length of a statement is
-# limited to 8KB.
-#
-# Without using prepared statements, it makes no sense to test
# BLOB data with DB2 or Firebird, because the length of a statement
# is limited to 32KB.
-unless current_adapter?(:SQLServerAdapter, :SybaseAdapter, :DB2Adapter, :FirebirdAdapter)
+unless current_adapter?(:SybaseAdapter, :DB2Adapter, :FirebirdAdapter)
require 'models/binary'
class BinaryTest < ActiveRecord::TestCase
diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb
index 0fa61500c0..8bd0dd0f6e 100644
--- a/activerecord/test/cases/calculations_test.rb
+++ b/activerecord/test/cases/calculations_test.rb
@@ -25,6 +25,11 @@ class CalculationsTest < ActiveRecord::TestCase
def test_should_return_nil_as_average
assert_nil NumericData.average(:bank_balance)
end
+
+ def test_type_cast_calculated_value_should_convert_db_averages_of_fixnum_class_to_decimal
+ assert_equal 0, NumericData.send(:type_cast_calculated_value, 0, nil, 'avg')
+ assert_equal 53.0, NumericData.send(:type_cast_calculated_value, 53, nil, 'avg')
+ end
def test_should_get_maximum_of_field
assert_equal 60, Account.maximum(:credit_limit)
diff --git a/activerecord/test/cases/defaults_test.rb b/activerecord/test/cases/defaults_test.rb
index 875b7f8dbc..b4032c23e6 100644
--- a/activerecord/test/cases/defaults_test.rb
+++ b/activerecord/test/cases/defaults_test.rb
@@ -18,12 +18,7 @@ class DefaultTest < ActiveRecord::TestCase
end
end
- if current_adapter?(:MysqlAdapter)
-
-
- end
-
- if current_adapter?(:PostgreSQLAdapter, :SQLServerAdapter, :FirebirdAdapter, :OpenBaseAdapter, :OracleAdapter)
+ if current_adapter?(:PostgreSQLAdapter, :FirebirdAdapter, :OpenBaseAdapter, :OracleAdapter)
def test_default_integers
default = Default.new
assert_instance_of Fixnum, default.positive_integer
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index 153880afbd..d4d770b04e 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -175,6 +175,13 @@ class FinderTest < ActiveRecord::TestCase
assert_equal 4, developers.map(&:salary).uniq.size
end
+ def test_find_with_group_and_having
+ developers = Developer.find(:all, :group => "salary", :having => "sum(salary) > 10000", :select => "salary")
+ assert_equal 3, developers.size
+ assert_equal 3, developers.map(&:salary).uniq.size
+ assert developers.all? { |developer| developer.salary > 10000 }
+ end
+
def test_find_with_entire_select_statement
topics = Topic.find_by_sql "SELECT * FROM topics WHERE author_name = 'Mary'"
diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb
index 6ba7597f56..ed2915b023 100644
--- a/activerecord/test/cases/fixtures_test.rb
+++ b/activerecord/test/cases/fixtures_test.rb
@@ -641,15 +641,15 @@ end
class FixtureLoadingTest < ActiveRecord::TestCase
uses_mocha 'reloading_fixtures_through_accessor_methods' do
def test_logs_message_for_failed_dependency_load
- Test::Unit::TestCase.expects(:require_dependency).with(:does_not_exist).raises(LoadError)
+ ActiveRecord::TestCase.expects(:require_dependency).with(:does_not_exist).raises(LoadError)
ActiveRecord::Base.logger.expects(:warn)
- Test::Unit::TestCase.try_to_load_dependency(:does_not_exist)
+ ActiveRecord::TestCase.try_to_load_dependency(:does_not_exist)
end
def test_does_not_logs_message_for_successful_dependency_load
- Test::Unit::TestCase.expects(:require_dependency).with(:works_out_fine)
+ ActiveRecord::TestCase.expects(:require_dependency).with(:works_out_fine)
ActiveRecord::Base.logger.expects(:warn).never
- Test::Unit::TestCase.try_to_load_dependency(:works_out_fine)
+ ActiveRecord::TestCase.try_to_load_dependency(:works_out_fine)
end
end
end
diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb
index 0c03d29dec..c18ecf6f8f 100644
--- a/activerecord/test/cases/helper.rb
+++ b/activerecord/test/cases/helper.rb
@@ -5,8 +5,8 @@ require 'config'
require 'test/unit'
require 'active_record'
-require 'active_record/fixtures'
require 'active_record/test_case'
+require 'active_record/fixtures'
require 'connection'
# Show backtraces for deprecated behavior for quicker cleanup.
@@ -48,15 +48,22 @@ class << ActiveRecord::Base
end
unless ENV['FIXTURE_DEBUG']
- module Test #:nodoc:
- module Unit #:nodoc:
- class << TestCase #:nodoc:
- def try_to_load_dependency_with_silence(*args)
- ActiveRecord::Base.logger.silence { try_to_load_dependency_without_silence(*args)}
- end
-
- alias_method_chain :try_to_load_dependency, :silence
- end
+ module ActiveRecord::TestFixtures::ClassMethods
+ def try_to_load_dependency_with_silence(*args)
+ ActiveRecord::Base.logger.silence { try_to_load_dependency_without_silence(*args)}
end
+
+ alias_method_chain :try_to_load_dependency, :silence
+ end
+end
+
+class ActiveSupport::TestCase
+ include ActiveRecord::TestFixtures
+ self.fixture_path = FIXTURES_ROOT
+ self.use_instantiated_fixtures = false
+ self.use_transactional_fixtures = true
+
+ def create_fixtures(*table_names, &block)
+ Fixtures.create_fixtures(ActiveSupport::TestCase.fixture_path, table_names, {}, &block)
end
-end \ No newline at end of file
+end
diff --git a/activerecord/test/cases/i18n_test.rb b/activerecord/test/cases/i18n_test.rb
index ea06e377e3..b1db662eca 100644
--- a/activerecord/test/cases/i18n_test.rb
+++ b/activerecord/test/cases/i18n_test.rb
@@ -9,32 +9,32 @@ class ActiveRecordI18nTests < Test::Unit::TestCase
end
def test_translated_model_attributes
- I18n.backend.store_translations 'en-US', :activerecord => {:attributes => {:topic => {:title => 'topic title attribute'} } }
+ I18n.backend.store_translations 'en', :activerecord => {:attributes => {:topic => {:title => 'topic title attribute'} } }
assert_equal 'topic title attribute', Topic.human_attribute_name('title')
end
def test_translated_model_attributes_with_sti
- I18n.backend.store_translations 'en-US', :activerecord => {:attributes => {:reply => {:title => 'reply title attribute'} } }
+ I18n.backend.store_translations 'en', :activerecord => {:attributes => {:reply => {:title => 'reply title attribute'} } }
assert_equal 'reply title attribute', Reply.human_attribute_name('title')
end
def test_translated_model_attributes_with_sti_fallback
- I18n.backend.store_translations 'en-US', :activerecord => {:attributes => {:topic => {:title => 'topic title attribute'} } }
+ I18n.backend.store_translations 'en', :activerecord => {:attributes => {:topic => {:title => 'topic title attribute'} } }
assert_equal 'topic title attribute', Reply.human_attribute_name('title')
end
def test_translated_model_names
- I18n.backend.store_translations 'en-US', :activerecord => {:models => {:topic => 'topic model'} }
+ I18n.backend.store_translations 'en', :activerecord => {:models => {:topic => 'topic model'} }
assert_equal 'topic model', Topic.human_name
end
def test_translated_model_names_with_sti
- I18n.backend.store_translations 'en-US', :activerecord => {:models => {:reply => 'reply model'} }
+ I18n.backend.store_translations 'en', :activerecord => {:models => {:reply => 'reply model'} }
assert_equal 'reply model', Reply.human_name
end
def test_translated_model_names_with_sti_fallback
- I18n.backend.store_translations 'en-US', :activerecord => {:models => {:topic => 'topic model'} }
+ I18n.backend.store_translations 'en', :activerecord => {:models => {:topic => 'topic model'} }
assert_equal 'topic model', Reply.human_name
end
end
diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb
index a39415618d..3f59eb9706 100644
--- a/activerecord/test/cases/inheritance_test.rb
+++ b/activerecord/test/cases/inheritance_test.rb
@@ -59,13 +59,13 @@ class InheritanceTest < ActiveRecord::TestCase
def test_a_bad_type_column
#SQLServer need to turn Identity Insert On before manually inserting into the Identity column
- if current_adapter?(:SQLServerAdapter, :SybaseAdapter)
+ if current_adapter?(:SybaseAdapter)
Company.connection.execute "SET IDENTITY_INSERT companies ON"
end
Company.connection.insert "INSERT INTO companies (id, #{QUOTED_TYPE}, name) VALUES(100, 'bad_class!', 'Not happening')"
#We then need to turn it back Off before continuing.
- if current_adapter?(:SQLServerAdapter, :SybaseAdapter)
+ if current_adapter?(:SybaseAdapter)
Company.connection.execute "SET IDENTITY_INSERT companies OFF"
end
assert_raises(ActiveRecord::SubclassNotFound) { Company.find(100) }
diff --git a/activerecord/test/cases/locking_test.rb b/activerecord/test/cases/locking_test.rb
index 0a14b1d906..077cac7747 100644
--- a/activerecord/test/cases/locking_test.rb
+++ b/activerecord/test/cases/locking_test.rb
@@ -200,9 +200,9 @@ end
# blocks, so separate script called by Kernel#system is needed.
# (See exec vs. async_exec in the PostgreSQL adapter.)
-# TODO: The SQL Server, Sybase, and OpenBase adapters currently have no support for pessimistic locking
+# TODO: The Sybase, and OpenBase adapters currently have no support for pessimistic locking
-unless current_adapter?(:SQLServerAdapter, :SybaseAdapter, :OpenBaseAdapter)
+unless current_adapter?(:SybaseAdapter, :OpenBaseAdapter)
class PessimisticLockingTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false
fixtures :people, :readers
diff --git a/activerecord/test/cases/method_scoping_test.rb b/activerecord/test/cases/method_scoping_test.rb
index ff10bfaf3e..6372b4f6aa 100644
--- a/activerecord/test/cases/method_scoping_test.rb
+++ b/activerecord/test/cases/method_scoping_test.rb
@@ -522,6 +522,73 @@ class HasAndBelongsToManyScopingTest< ActiveRecord::TestCase
end
+class DefaultScopingTest < ActiveRecord::TestCase
+ fixtures :developers
+
+ def test_default_scope
+ expected = Developer.find(:all, :order => 'salary DESC').collect { |dev| dev.salary }
+ received = DeveloperOrderedBySalary.find(:all).collect { |dev| dev.salary }
+ assert_equal expected, received
+ end
+
+ def test_default_scoping_with_threads
+ scope = [{ :create => {}, :find => { :order => 'salary DESC' } }]
+
+ 2.times do
+ Thread.new { assert_equal scope, DeveloperOrderedBySalary.send(:scoped_methods) }.join
+ end
+ end
+
+ def test_default_scoping_with_inheritance
+ scope = [{ :create => {}, :find => { :order => 'salary DESC' } }]
+
+ # Inherit a class having a default scope and define a new default scope
+ klass = Class.new(DeveloperOrderedBySalary)
+ klass.send :default_scope, {}
+
+ # Scopes added on children should append to parent scope
+ expected_klass_scope = [{ :create => {}, :find => { :order => 'salary DESC' }}, { :create => {}, :find => {} }]
+ assert_equal expected_klass_scope, klass.send(:scoped_methods)
+
+ # Parent should still have the original scope
+ assert_equal scope, DeveloperOrderedBySalary.send(:scoped_methods)
+ end
+
+ def test_method_scope
+ expected = Developer.find(:all, :order => 'name DESC').collect { |dev| dev.salary }
+ received = DeveloperOrderedBySalary.all_ordered_by_name.collect { |dev| dev.salary }
+ assert_equal expected, received
+ end
+
+ def test_nested_scope
+ expected = Developer.find(:all, :order => 'name DESC').collect { |dev| dev.salary }
+ received = DeveloperOrderedBySalary.with_scope(:find => { :order => 'name DESC'}) do
+ DeveloperOrderedBySalary.find(:all).collect { |dev| dev.salary }
+ end
+ assert_equal expected, received
+ end
+
+ def test_named_scope
+ expected = Developer.find(:all, :order => 'name DESC').collect { |dev| dev.salary }
+ received = DeveloperOrderedBySalary.by_name.find(:all).collect { |dev| dev.salary }
+ assert_equal expected, received
+ end
+
+ def test_nested_exclusive_scope
+ expected = Developer.find(:all, :limit => 100).collect { |dev| dev.salary }
+ received = DeveloperOrderedBySalary.with_exclusive_scope(:find => { :limit => 100 }) do
+ DeveloperOrderedBySalary.find(:all).collect { |dev| dev.salary }
+ end
+ assert_equal expected, received
+ end
+
+ def test_overwriting_default_scope
+ expected = Developer.find(:all, :order => 'salary').collect { |dev| dev.salary }
+ received = DeveloperOrderedBySalary.find(:all, :order => 'salary').collect { |dev| dev.salary }
+ assert_equal expected, received
+ end
+end
+
=begin
# We disabled the scoping for has_one and belongs_to as we can't think of a proper use case
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index ac44dd7ffe..2ec3d40332 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -271,9 +271,9 @@ if ActiveRecord::Base.connection.supports_migrations?
Person.connection.drop_table table_name rescue nil
end
- # SQL Server, Sybase, and SQLite3 will not allow you to add a NOT NULL
+ # Sybase, and SQLite3 will not allow you to add a NOT NULL
# column to a table without a default value.
- unless current_adapter?(:SQLServerAdapter, :SybaseAdapter, :SQLiteAdapter)
+ unless current_adapter?(:SybaseAdapter, :SQLiteAdapter)
def test_add_column_not_null_without_default
Person.connection.create_table :testings do |t|
t.column :foo, :string
@@ -410,7 +410,7 @@ if ActiveRecord::Base.connection.supports_migrations?
assert_equal Fixnum, bob.age.class
assert_equal Time, bob.birthday.class
- if current_adapter?(:SQLServerAdapter, :OracleAdapter, :SybaseAdapter)
+ if current_adapter?(:OracleAdapter, :SybaseAdapter)
# Sybase, and Oracle don't differentiate between date/time
assert_equal Time, bob.favorite_day.class
else
@@ -851,10 +851,6 @@ if ActiveRecord::Base.connection.supports_migrations?
# - SQLite3 stores a float, in violation of SQL
assert_kind_of BigDecimal, b.value_of_e
assert_equal BigDecimal("2.71828182845905"), b.value_of_e
- elsif current_adapter?(:SQLServer)
- # - SQL Server rounds instead of truncating
- assert_kind_of Fixnum, b.value_of_e
- assert_equal 3, b.value_of_e
else
# - SQL standard is an integer
assert_kind_of Fixnum, b.value_of_e
diff --git a/activerecord/test/cases/pooled_connections_test.rb b/activerecord/test/cases/pooled_connections_test.rb
index 078ca1d679..2649a9358a 100644
--- a/activerecord/test/cases/pooled_connections_test.rb
+++ b/activerecord/test/cases/pooled_connections_test.rb
@@ -28,10 +28,13 @@ class PooledConnectionsTest < ActiveRecord::TestCase
end
end
- def test_pooled_connection_checkout
- checkout_connections
- assert_equal @connections.length, 2
- assert_equal @timed_out, 2
+ # Will deadlock due to lack of Monitor timeouts in 1.9
+ if RUBY_VERSION < '1.9'
+ def test_pooled_connection_checkout
+ checkout_connections
+ assert_equal @connections.length, 2
+ assert_equal @timed_out, 2
+ end
end
def checkout_checkin_connections(pool_size, threads)
@@ -73,6 +76,19 @@ class PooledConnectionsTest < ActiveRecord::TestCase
assert ActiveRecord::ConnectionAdapters::AbstractAdapter === conn
conn_pool.checkin(conn)
end
+
+ def test_not_connected_defined_connection_returns_false
+ ActiveRecord::Base.establish_connection(@connection)
+ assert ! ActiveRecord::Base.connected?
+ end
+
+ def test_undefined_connection_returns_false
+ old_handler = ActiveRecord::Base.connection_handler
+ ActiveRecord::Base.connection_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
+ assert_equal false, ActiveRecord::Base.connected?
+ ensure
+ ActiveRecord::Base.connection_handler = old_handler
+ end
end unless %w(FrontBase).include? ActiveRecord::Base.connection.adapter_name
class AllowConcurrencyDeprecatedTest < ActiveRecord::TestCase
diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb
index ee7e285a73..17e4c755ce 100644
--- a/activerecord/test/cases/schema_dumper_test.rb
+++ b/activerecord/test/cases/schema_dumper_test.rb
@@ -1,5 +1,4 @@
require "cases/helper"
-require 'active_record/schema_dumper'
require 'stringio'
diff --git a/activerecord/test/cases/table_name_test_sqlserver.rb b/activerecord/test/cases/table_name_test_sqlserver.rb
deleted file mode 100644
index fbf38a130e..0000000000
--- a/activerecord/test/cases/table_name_test_sqlserver.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-require "cases/helper"
-require 'active_record/schema'
-
-if ActiveRecord::Base.connection.supports_migrations?
- class Order < ActiveRecord::Base
- self.table_name = '[order]'
- end
-
- class TableNameTest < ActiveRecord::TestCase
- self.use_transactional_fixtures = false
-
- # Ensures Model.columns works when using SQLServer escape characters.
- # Enables legacy schemas using SQL reserved words as table names.
- # Should work with table names with spaces as well ('table name').
- def test_escaped_table_name
- assert_nothing_raised do
- ActiveRecord::Base.connection.select_all 'SELECT * FROM [order]'
- end
- assert_equal '[order]', Order.table_name
- assert_equal 5, Order.columns.length
- end
- end
-end
diff --git a/activerecord/test/cases/validations_i18n_test.rb b/activerecord/test/cases/validations_i18n_test.rb
index 42246f18b6..f59e3f7001 100644
--- a/activerecord/test/cases/validations_i18n_test.rb
+++ b/activerecord/test/cases/validations_i18n_test.rb
@@ -2,14 +2,14 @@ require "cases/helper"
require 'models/topic'
require 'models/reply'
-class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
+class ActiveRecordValidationsI18nTests < ActiveSupport::TestCase
def setup
reset_callbacks Topic
@topic = Topic.new
@old_load_path, @old_backend = I18n.load_path, I18n.backend
I18n.load_path.clear
I18n.backend = I18n::Backend::Simple.new
- I18n.backend.store_translations('en-US', :activerecord => {:errors => {:messages => {:custom => nil}}})
+ I18n.backend.store_translations('en', :activerecord => {:errors => {:messages => {:custom => nil}}})
end
def teardown
@@ -165,7 +165,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
def test_errors_full_messages_translates_human_attribute_name_for_model_attributes
@topic.errors.instance_variable_set :@errors, { 'title' => ['empty'] }
I18n.expects(:translate).with(:"topic.title", :default => ['Title'], :scope => [:activerecord, :attributes], :count => 1).returns('Title')
- @topic.errors.full_messages :locale => 'en-US'
+ @topic.errors.full_messages :locale => 'en'
end
end
@@ -429,8 +429,8 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
# validates_confirmation_of w/o mocha
def test_validates_confirmation_of_finds_custom_model_key_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:confirmation => 'custom message'}}}}}}
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:confirmation => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:confirmation => 'custom message'}}}}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:confirmation => 'global message'}}}
Topic.validates_confirmation_of :title
@topic.title_confirmation = 'foo'
@@ -439,7 +439,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
end
def test_validates_confirmation_of_finds_global_default_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:confirmation => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:confirmation => 'global message'}}}
Topic.validates_confirmation_of :title
@topic.title_confirmation = 'foo'
@@ -450,8 +450,8 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
# validates_acceptance_of w/o mocha
def test_validates_acceptance_of_finds_custom_model_key_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:accepted => 'custom message'}}}}}}
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:accepted => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:accepted => 'custom message'}}}}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:accepted => 'global message'}}}
Topic.validates_acceptance_of :title, :allow_nil => false
@topic.valid?
@@ -459,7 +459,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
end
def test_validates_acceptance_of_finds_global_default_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:accepted => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:accepted => 'global message'}}}
Topic.validates_acceptance_of :title, :allow_nil => false
@topic.valid?
@@ -469,8 +469,8 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
# validates_presence_of w/o mocha
def test_validates_presence_of_finds_custom_model_key_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:blank => 'custom message'}}}}}}
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:blank => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:blank => 'custom message'}}}}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:blank => 'global message'}}}
Topic.validates_presence_of :title
@topic.valid?
@@ -478,7 +478,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
end
def test_validates_presence_of_finds_global_default_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:blank => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:blank => 'global message'}}}
Topic.validates_presence_of :title
@topic.valid?
@@ -488,8 +488,8 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
# validates_length_of :within w/o mocha
def test_validates_length_of_within_finds_custom_model_key_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:too_short => 'custom message'}}}}}}
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:too_short => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:too_short => 'custom message'}}}}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:too_short => 'global message'}}}
Topic.validates_length_of :title, :within => 3..5
@topic.valid?
@@ -497,7 +497,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
end
def test_validates_length_of_within_finds_global_default_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:too_short => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:too_short => 'global message'}}}
Topic.validates_length_of :title, :within => 3..5
@topic.valid?
@@ -507,8 +507,8 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
# validates_length_of :is w/o mocha
def test_validates_length_of_within_finds_custom_model_key_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}}
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}}
Topic.validates_length_of :title, :is => 5
@topic.valid?
@@ -516,7 +516,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
end
def test_validates_length_of_within_finds_global_default_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}}
Topic.validates_length_of :title, :is => 5
@topic.valid?
@@ -526,8 +526,8 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
# validates_uniqueness_of w/o mocha
def test_validates_length_of_within_finds_custom_model_key_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}}
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}}
Topic.validates_length_of :title, :is => 5
@topic.valid?
@@ -535,7 +535,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
end
def test_validates_length_of_within_finds_global_default_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}}
Topic.validates_length_of :title, :is => 5
@topic.valid?
@@ -546,8 +546,8 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
# validates_format_of w/o mocha
def test_validates_format_of_finds_custom_model_key_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:invalid => 'custom message'}}}}}}
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:invalid => 'custom message'}}}}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}}
Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/
@topic.valid?
@@ -555,7 +555,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
end
def test_validates_format_of_finds_global_default_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}}
Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/
@topic.valid?
@@ -565,8 +565,8 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
# validates_inclusion_of w/o mocha
def test_validates_inclusion_of_finds_custom_model_key_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:inclusion => 'custom message'}}}}}}
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:inclusion => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:inclusion => 'custom message'}}}}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:inclusion => 'global message'}}}
Topic.validates_inclusion_of :title, :in => %w(a b c)
@topic.valid?
@@ -574,7 +574,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
end
def test_validates_inclusion_of_finds_global_default_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:inclusion => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:inclusion => 'global message'}}}
Topic.validates_inclusion_of :title, :in => %w(a b c)
@topic.valid?
@@ -584,8 +584,8 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
# validates_exclusion_of w/o mocha
def test_validates_exclusion_of_finds_custom_model_key_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:exclusion => 'custom message'}}}}}}
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:exclusion => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:exclusion => 'custom message'}}}}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:exclusion => 'global message'}}}
Topic.validates_exclusion_of :title, :in => %w(a b c)
@topic.title = 'a'
@@ -594,7 +594,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
end
def test_validates_exclusion_of_finds_global_default_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:exclusion => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:exclusion => 'global message'}}}
Topic.validates_exclusion_of :title, :in => %w(a b c)
@topic.title = 'a'
@@ -605,8 +605,8 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
# validates_numericality_of without :only_integer w/o mocha
def test_validates_numericality_of_finds_custom_model_key_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:not_a_number => 'custom message'}}}}}}
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:not_a_number => 'custom message'}}}}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}}
Topic.validates_numericality_of :title
@topic.title = 'a'
@@ -615,7 +615,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
end
def test_validates_numericality_of_finds_global_default_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}}
Topic.validates_numericality_of :title, :only_integer => true
@topic.title = 'a'
@@ -626,8 +626,8 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
# validates_numericality_of with :only_integer w/o mocha
def test_validates_numericality_of_only_integer_finds_custom_model_key_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:not_a_number => 'custom message'}}}}}}
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:not_a_number => 'custom message'}}}}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}}
Topic.validates_numericality_of :title, :only_integer => true
@topic.title = 'a'
@@ -636,7 +636,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
end
def test_validates_numericality_of_only_integer_finds_global_default_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}}
Topic.validates_numericality_of :title, :only_integer => true
@topic.title = 'a'
@@ -647,8 +647,8 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
# validates_numericality_of :odd w/o mocha
def test_validates_numericality_of_odd_finds_custom_model_key_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:odd => 'custom message'}}}}}}
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:odd => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:odd => 'custom message'}}}}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:odd => 'global message'}}}
Topic.validates_numericality_of :title, :only_integer => true, :odd => true
@topic.title = 0
@@ -657,7 +657,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
end
def test_validates_numericality_of_odd_finds_global_default_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:odd => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:odd => 'global message'}}}
Topic.validates_numericality_of :title, :only_integer => true, :odd => true
@topic.title = 0
@@ -668,8 +668,8 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
# validates_numericality_of :less_than w/o mocha
def test_validates_numericality_of_less_than_finds_custom_model_key_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:less_than => 'custom message'}}}}}}
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:less_than => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:less_than => 'custom message'}}}}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:less_than => 'global message'}}}
Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0
@topic.title = 1
@@ -678,7 +678,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
end
def test_validates_numericality_of_less_than_finds_global_default_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:less_than => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:less_than => 'global message'}}}
Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0
@topic.title = 1
@@ -690,8 +690,8 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
# validates_associated w/o mocha
def test_validates_associated_finds_custom_model_key_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:replies => {:invalid => 'custom message'}}}}}}
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:replies => {:invalid => 'custom message'}}}}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}}
Topic.validates_associated :replies
replied_topic.valid?
@@ -699,7 +699,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
end
def test_validates_associated_finds_global_default_translation
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}}
Topic.validates_associated :replies
replied_topic.valid?
@@ -707,7 +707,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
end
def test_validations_with_message_symbol_must_translate
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:messages => {:custom_error => "I am a custom error"}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:custom_error => "I am a custom error"}}}
Topic.validates_presence_of :title, :message => :custom_error
@topic.title = nil
@topic.valid?
@@ -715,7 +715,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
end
def test_validates_with_message_symbol_must_translate_per_attribute
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:custom_error => "I am a custom error"}}}}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:custom_error => "I am a custom error"}}}}}}
Topic.validates_presence_of :title, :message => :custom_error
@topic.title = nil
@topic.valid?
@@ -723,7 +723,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
end
def test_validates_with_message_symbol_must_translate_per_model
- I18n.backend.store_translations 'en-US', :activerecord => {:errors => {:models => {:topic => {:custom_error => "I am a custom error"}}}}
+ I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:custom_error => "I am a custom error"}}}}
Topic.validates_presence_of :title, :message => :custom_error
@topic.title = nil
@topic.valid?
@@ -743,7 +743,7 @@ class ActiveRecordValidationsGenerateMessageI18nTests < Test::Unit::TestCase
def setup
reset_callbacks Topic
@topic = Topic.new
- I18n.backend.store_translations :'en-US', {
+ I18n.backend.store_translations :'en', {
:activerecord => {
:errors => {
:messages => {
diff --git a/activerecord/test/fixtures/organizations.yml b/activerecord/test/fixtures/organizations.yml
new file mode 100644
index 0000000000..25295bff87
--- /dev/null
+++ b/activerecord/test/fixtures/organizations.yml
@@ -0,0 +1,5 @@
+nsa:
+ name: No Such Agency
+discordians:
+ name: Discordians
+
diff --git a/activerecord/test/models/author.rb b/activerecord/test/models/author.rb
index e5b19ff9e4..4ffac4fe32 100644
--- a/activerecord/test/models/author.rb
+++ b/activerecord/test/models/author.rb
@@ -1,6 +1,7 @@
class Author < ActiveRecord::Base
has_many :posts
has_many :posts_with_comments, :include => :comments, :class_name => "Post"
+ has_many :popular_grouped_posts, :include => :comments, :class_name => "Post", :group => "type", :having => "SUM(comments_count) > 1", :select => "type"
has_many :posts_with_comments_sorted_by_comment_id, :include => :comments, :class_name => "Post", :order => 'comments.id'
has_many :posts_sorted_by_id_limited, :class_name => "Post", :order => 'posts.id', :limit => 1
has_many :posts_with_categories, :include => :categories, :class_name => "Post"
diff --git a/activerecord/test/models/category.rb b/activerecord/test/models/category.rb
index 4e9d247a4e..5efce6aaa6 100644
--- a/activerecord/test/models/category.rb
+++ b/activerecord/test/models/category.rb
@@ -14,6 +14,7 @@ class Category < ActiveRecord::Base
:class_name => 'Post',
:conditions => { :title => 'Yet Another Testing Title' }
+ has_and_belongs_to_many :popular_grouped_posts, :class_name => "Post", :group => "posts.type", :having => "sum(comments.post_id) > 2", :include => :comments
has_and_belongs_to_many :posts_gruoped_by_title, :class_name => "Post", :group => "title", :select => "title"
def self.what_are_you
diff --git a/activerecord/test/models/developer.rb b/activerecord/test/models/developer.rb
index c08476f728..92039a4f54 100644
--- a/activerecord/test/models/developer.rb
+++ b/activerecord/test/models/developer.rb
@@ -77,3 +77,15 @@ class DeveloperWithBeforeDestroyRaise < ActiveRecord::Base
raise if projects.empty?
end
end
+
+class DeveloperOrderedBySalary < ActiveRecord::Base
+ self.table_name = 'developers'
+ default_scope :order => 'salary DESC'
+ named_scope :by_name, :order => 'name DESC'
+
+ def self.all_ordered_by_name
+ with_scope(:find => { :order => 'name DESC' }) do
+ find(:all)
+ end
+ end
+end
diff --git a/activerecord/test/models/member.rb b/activerecord/test/models/member.rb
index 688725f200..77a37abb38 100644
--- a/activerecord/test/models/member.rb
+++ b/activerecord/test/models/member.rb
@@ -6,4 +6,6 @@ class Member < ActiveRecord::Base
has_one :favourite_club, :through => :memberships, :conditions => ["memberships.favourite = ?", true], :source => :club
has_one :sponsor, :as => :sponsorable
has_one :sponsor_club, :through => :sponsor
+ has_one :member_detail
+ has_one :organization, :through => :member_detail
end \ No newline at end of file
diff --git a/activerecord/test/models/member_detail.rb b/activerecord/test/models/member_detail.rb
new file mode 100644
index 0000000000..e731454556
--- /dev/null
+++ b/activerecord/test/models/member_detail.rb
@@ -0,0 +1,4 @@
+class MemberDetail < ActiveRecord::Base
+ belongs_to :member
+ belongs_to :organization
+end
diff --git a/activerecord/test/models/organization.rb b/activerecord/test/models/organization.rb
new file mode 100644
index 0000000000..d79d5037c8
--- /dev/null
+++ b/activerecord/test/models/organization.rb
@@ -0,0 +1,4 @@
+class Organization < ActiveRecord::Base
+ has_many :member_details
+ has_many :members, :through => :member_details
+end \ No newline at end of file
diff --git a/activerecord/test/models/project.rb b/activerecord/test/models/project.rb
index 44c692b5e7..550d4ae23c 100644
--- a/activerecord/test/models/project.rb
+++ b/activerecord/test/models/project.rb
@@ -13,6 +13,7 @@ class Project < ActiveRecord::Base
:after_add => Proc.new {|o, r| o.developers_log << "after_adding#{r.id || '<new>'}"},
:before_remove => Proc.new {|o, r| o.developers_log << "before_removing#{r.id}"},
:after_remove => Proc.new {|o, r| o.developers_log << "after_removing#{r.id}"}
+ has_and_belongs_to_many :well_payed_salary_groups, :class_name => "Developer", :group => "salary", :having => "SUM(salary) > 10000", :select => "SUM(salary) as salary"
attr_accessor :developers_log
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index ab5c7c520b..6217e3bc1c 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -197,6 +197,12 @@ ActiveRecord::Schema.define do
t.string :name
end
+ create_table :member_details, :force => true do |t|
+ t.integer :member_id
+ t.integer :organization_id
+ t.string :extra_data
+ end
+
create_table :memberships, :force => true do |t|
t.datetime :joined_on
t.integer :club_id, :member_id
@@ -249,6 +255,10 @@ ActiveRecord::Schema.define do
t.integer :shipping_customer_id
end
+ create_table :organizations, :force => true do |t|
+ t.string :name
+ end
+
create_table :owners, :primary_key => :owner_id ,:force => true do |t|
t.string :name
end
diff --git a/activerecord/test/schema/sqlserver_specific_schema.rb b/activerecord/test/schema/sqlserver_specific_schema.rb
deleted file mode 100644
index cd8aca2fe5..0000000000
--- a/activerecord/test/schema/sqlserver_specific_schema.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-ActiveRecord::Schema.define do
- create_table :table_with_real_columns, :force => true do |t|
- t.column :real_number, :real
- end
-end \ No newline at end of file