aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG29
-rw-r--r--activerecord/activerecord.gemspec2
-rw-r--r--activerecord/lib/active_record/aggregations.rb2
-rw-r--r--activerecord/lib/active_record/associations.rb40
-rw-r--r--activerecord/lib/active_record/associations/association_collection.rb21
-rw-r--r--activerecord/lib/active_record/associations/association_proxy.rb8
-rw-r--r--activerecord/lib/active_record/associations/belongs_to_association.rb6
-rw-r--r--activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/has_many_through_association.rb5
-rw-r--r--activerecord/lib/active_record/associations/has_one_association.rb12
-rw-r--r--activerecord/lib/active_record/associations/has_one_through_association.rb2
-rw-r--r--activerecord/lib/active_record/attribute_methods/primary_key.rb7
-rw-r--r--activerecord/lib/active_record/autosave_association.rb14
-rw-r--r--activerecord/lib/active_record/base.rb18
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql_adapter.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb16
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb22
-rw-r--r--activerecord/lib/active_record/locking/optimistic.rb2
-rw-r--r--activerecord/lib/active_record/locking/pessimistic.rb2
-rw-r--r--activerecord/lib/active_record/nested_attributes.rb2
-rw-r--r--activerecord/lib/active_record/persistence.rb11
-rw-r--r--activerecord/lib/active_record/railtie.rb2
-rw-r--r--activerecord/lib/active_record/relation/finder_methods.rb12
-rw-r--r--activerecord/lib/active_record/session_store.rb9
-rw-r--r--activerecord/lib/active_record/timestamp.rb2
-rw-r--r--activerecord/lib/active_record/transactions.rb12
-rw-r--r--activerecord/lib/active_record/validations.rb2
-rw-r--r--activerecord/lib/active_record/validations/uniqueness.rb44
-rw-r--r--activerecord/test/cases/adapters/mysql/connection_test.rb26
-rw-r--r--activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb18
-rw-r--r--activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb4
-rw-r--r--activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb24
-rw-r--r--activerecord/test/cases/associations/belongs_to_associations_test.rb12
-rw-r--r--activerecord/test/cases/associations/cascaded_eager_loading_test.rb2
-rw-r--r--activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb2
-rw-r--r--activerecord/test/cases/associations/eager_test.rb16
-rw-r--r--activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb32
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb39
-rw-r--r--activerecord/test/cases/associations/has_many_through_associations_test.rb7
-rw-r--r--activerecord/test/cases/associations/has_one_associations_test.rb4
-rw-r--r--activerecord/test/cases/associations/join_model_test.rb16
-rw-r--r--activerecord/test/cases/autosave_association_test.rb86
-rw-r--r--activerecord/test/cases/base_test.rb14
-rw-r--r--activerecord/test/cases/dirty_test.rb14
-rw-r--r--activerecord/test/cases/finder_test.rb52
-rw-r--r--activerecord/test/cases/helper.rb10
-rw-r--r--activerecord/test/cases/nested_attributes_test.rb24
-rw-r--r--activerecord/test/cases/persistence_test.rb9
-rw-r--r--activerecord/test/cases/reflection_test.rb10
-rw-r--r--activerecord/test/cases/relations_test.rb23
-rw-r--r--activerecord/test/cases/session_store/sql_bypass.rb4
-rw-r--r--activerecord/test/cases/transactions_test.rb16
-rw-r--r--activerecord/test/connections/native_oracle/connection.rb12
-rw-r--r--activerecord/test/models/eye.rb2
-rw-r--r--activerecord/test/models/pirate.rb2
-rw-r--r--activerecord/test/models/subject.rb2
-rw-r--r--activerecord/test/models/topic.rb2
-rw-r--r--activerecord/test/schema/schema.rb1
59 files changed, 441 insertions, 356 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index d3530e0da9..11eb47917d 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -18,6 +18,35 @@
[Aaron Patterson]
+*Rails 3.0.2 (unreleased)*
+
+* reorder is deprecated in favor of except(:order).order(...) [Santiago Pastorino]
+
+* except is now AR public API
+
+ Model.order('name').except(:order).order('salary')
+
+ generates:
+
+ SELECT * FROM models ORDER BY salary
+
+ [Santiago Pastorino]
+
+* The following code:
+
+ Model.limit(10).scoping { Model.count }
+
+ now generates the following SQL:
+
+ SELECT COUNT(*) FROM models LIMIT 10
+
+ This may not return what you want. Instead, you may with to do something
+ like this:
+
+ Model.limit(10).scoping { Model.all.size }
+
+ [Aaron Patterson]
+
*Rails 3.0.1 (October 15, 2010)*
* Introduce a fix for CVE-2010-3993
diff --git a/activerecord/activerecord.gemspec b/activerecord/activerecord.gemspec
index b8a980b1fb..b1df24844a 100644
--- a/activerecord/activerecord.gemspec
+++ b/activerecord/activerecord.gemspec
@@ -23,6 +23,6 @@ Gem::Specification.new do |s|
s.add_dependency('activesupport', version)
s.add_dependency('activemodel', version)
- s.add_dependency('arel', '~> 2.0.0')
+ s.add_dependency('arel', '~> 2.0.2')
s.add_dependency('tzinfo', '~> 0.3.23')
end
diff --git a/activerecord/lib/active_record/aggregations.rb b/activerecord/lib/active_record/aggregations.rb
index 16206c1056..8cd7389005 100644
--- a/activerecord/lib/active_record/aggregations.rb
+++ b/activerecord/lib/active_record/aggregations.rb
@@ -6,7 +6,7 @@ module ActiveRecord
def clear_aggregation_cache #:nodoc:
self.class.reflect_on_all_aggregations.to_a.each do |assoc|
instance_variable_set "@#{assoc.name}", nil
- end unless self.new_record?
+ end if self.persisted?
end
# Active Record implements aggregation through a macro-like class method called +composed_of+
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index dc466eafc2..08a4ebfd7e 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -118,7 +118,7 @@ module ActiveRecord
def clear_association_cache #:nodoc:
self.class.reflect_on_all_associations.to_a.each do |assoc|
instance_variable_set "@#{assoc.name}", nil
- end unless self.new_record?
+ end if self.persisted?
end
private
@@ -1839,8 +1839,6 @@ module ActiveRecord
@join_parts = [JoinBase.new(base, joins)]
@associations = {}
@reflections = []
- @base_records_hash = {}
- @base_records_in_order = []
@table_aliases = Hash.new(0)
@table_aliases[base.table_name] = 1
build(associations)
@@ -1874,15 +1872,18 @@ module ActiveRecord
end
def instantiate(rows)
- rows.each_with_index do |row, i|
- primary_id = join_base.record_id(row)
- unless @base_records_hash[primary_id]
- @base_records_in_order << (@base_records_hash[primary_id] = join_base.instantiate(row))
- end
- construct(@base_records_hash[primary_id], @associations, join_associations.dup, row)
- end
- remove_duplicate_results!(join_base.active_record, @base_records_in_order, @associations)
- return @base_records_in_order
+ primary_key = join_base.aliased_primary_key
+ parents = {}
+
+ records = rows.map { |model|
+ primary_id = model[primary_key]
+ parent = parents[primary_id] ||= join_base.instantiate(model)
+ construct(parent, @associations, join_associations.dup, model)
+ parent
+ }.uniq
+
+ remove_duplicate_results!(join_base.active_record, records, @associations)
+ records
end
def remove_duplicate_results!(base, records, associations)
@@ -1982,10 +1983,13 @@ module ActiveRecord
def construct(parent, associations, join_parts, row)
case associations
when Symbol, String
+ name = associations.to_s
+
join_part = join_parts.detect { |j|
- j.reflection.name.to_s == associations.to_s &&
+ j.reflection.name.to_s == name &&
j.parent_table_name == parent.class.table_name }
- raise(ConfigurationError, "No such association") if join_part.nil?
+
+ raise(ConfigurationError, "No such association") unless join_part
join_parts.delete(join_part)
construct_association(parent, join_part, row)
@@ -1995,13 +1999,7 @@ module ActiveRecord
end
when Hash
associations.sort_by { |k,_| k.to_s }.each do |name, assoc|
- join_part = join_parts.detect{ |j|
- j.reflection.name.to_s == name.to_s &&
- j.parent_table_name == parent.class.table_name }
- raise(ConfigurationError, "No such association") if join_part.nil?
-
- association = construct_association(parent, join_part, row)
- join_parts.delete(join_part)
+ association = construct(parent, name, join_parts, row)
construct(association, assoc, join_parts, row) if association
end
else
diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb
index 896e18af01..5b34ac907c 100644
--- a/activerecord/lib/active_record/associations/association_collection.rb
+++ b/activerecord/lib/active_record/associations/association_collection.rb
@@ -75,6 +75,7 @@ module ActiveRecord
find(:first, *args)
else
load_target unless loaded?
+ args = args[1..-1] if args.first.kind_of?(Hash) && args.first.empty?
@target.first(*args)
end
end
@@ -120,13 +121,13 @@ module ActiveRecord
# Since << flattens its argument list and inserts each record, +push+ and +concat+ behave identically.
def <<(*records)
result = true
- load_target if @owner.new_record?
+ load_target unless @owner.persisted?
transaction do
flatten_deeper(records).each do |record|
raise_on_type_mismatch(record)
add_record_to_target_with_callbacks(record) do |r|
- result &&= insert_record(record) unless @owner.new_record?
+ result &&= insert_record(record) if @owner.persisted?
end
end
end
@@ -285,12 +286,12 @@ module ActiveRecord
# This method is abstract in the sense that it relies on
# +count_records+, which is a method descendants have to provide.
def size
- if @owner.new_record? || (loaded? && !@reflection.options[:uniq])
+ if !@owner.persisted? || (loaded? && !@reflection.options[:uniq])
@target.size
elsif !loaded? && @reflection.options[:group]
load_target.size
elsif !loaded? && !@reflection.options[:uniq] && @target.is_a?(Array)
- unsaved_records = @target.select { |r| r.new_record? }
+ unsaved_records = @target.reject { |r| r.persisted? }
unsaved_records.size + count_records
else
count_records
@@ -357,7 +358,7 @@ module ActiveRecord
def include?(record)
return false unless record.is_a?(@reflection.klass)
- return include_in_memory?(record) if record.new_record?
+ return include_in_memory?(record) unless record.persisted?
load_target if @reflection.options[:finder_sql] && !loaded?
return @target.include?(record) if loaded?
exists?(record)
@@ -372,7 +373,7 @@ module ActiveRecord
end
def load_target
- if !@owner.new_record? || foreign_key_present
+ if @owner.persisted? || foreign_key_present
begin
if !loaded?
if @target.is_a?(Array) && @target.any?
@@ -513,7 +514,7 @@ module ActiveRecord
transaction do
records.each { |record| callback(:before_remove, record) }
- old_records = records.reject { |r| r.new_record? }
+ old_records = records.select { |r| r.persisted? }
yield(records, old_records)
records.each { |record| callback(:after_remove, record) }
end
@@ -538,14 +539,14 @@ module ActiveRecord
end
def ensure_owner_is_not_new
- if @owner.new_record?
+ unless @owner.persisted?
raise ActiveRecord::RecordNotSaved, "You cannot call create unless the parent is saved"
end
end
def fetch_first_or_last_using_find?(args)
- args.first.kind_of?(Hash) || !(loaded? || @owner.new_record? || @reflection.options[:finder_sql] ||
- @target.any? { |record| record.new_record? } || args.first.kind_of?(Integer))
+ (args.first.kind_of?(Hash) && !args.first.empty?) || !(loaded? || !@owner.persisted? || @reflection.options[:finder_sql] ||
+ !@target.all? { |record| record.persisted? } || args.first.kind_of?(Integer))
end
def include_in_memory?(record)
diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb
index 0c12c3737d..09bba213ce 100644
--- a/activerecord/lib/active_record/associations/association_proxy.rb
+++ b/activerecord/lib/active_record/associations/association_proxy.rb
@@ -53,7 +53,7 @@ module ActiveRecord
alias_method :proxy_respond_to?, :respond_to?
alias_method :proxy_extend, :extend
delegate :to_param, :to => :proxy_target
- instance_methods.each { |m| undef_method m unless m.to_s =~ /^(?:nil\?|send|object_id|to_a)$|^__|proxy_/ }
+ instance_methods.each { |m| undef_method m unless m.to_s =~ /^(?:nil\?|send|object_id|to_a)$|^__|^respond_to_missing|proxy_/ }
def initialize(owner, reflection)
@owner, @reflection = owner, reflection
@@ -175,10 +175,10 @@ module ActiveRecord
# If the association is polymorphic the type of the owner is also set.
def set_belongs_to_association_for(record)
if @reflection.options[:as]
- record["#{@reflection.options[:as]}_id"] = @owner.id unless @owner.new_record?
+ record["#{@reflection.options[:as]}_id"] = @owner.id if @owner.persisted?
record["#{@reflection.options[:as]}_type"] = @owner.class.base_class.name.to_s
else
- unless @owner.new_record?
+ if @owner.persisted?
primary_key = @reflection.options[:primary_key] || :id
record[@reflection.primary_key_name] = @owner.send(primary_key)
end
@@ -252,7 +252,7 @@ module ActiveRecord
def load_target
return nil unless defined?(@loaded)
- if !loaded? and (!@owner.new_record? || foreign_key_present)
+ if !loaded? and (@owner.persisted? || foreign_key_present)
@target = find_target
end
diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb
index 34b6cd5576..b624951cd9 100644
--- a/activerecord/lib/active_record/associations/belongs_to_association.rb
+++ b/activerecord/lib/active_record/associations/belongs_to_association.rb
@@ -14,7 +14,7 @@ module ActiveRecord
counter_cache_name = @reflection.counter_cache_column
if record.nil?
- if counter_cache_name && !@owner.new_record?
+ if counter_cache_name && @owner.persisted?
@reflection.klass.decrement_counter(counter_cache_name, previous_record_id) if @owner[@reflection.primary_key_name]
end
@@ -22,13 +22,13 @@ module ActiveRecord
else
raise_on_type_mismatch(record)
- if counter_cache_name && !@owner.new_record? && record.id != @owner[@reflection.primary_key_name]
+ if counter_cache_name && @owner.persisted? && record.id != @owner[@reflection.primary_key_name]
@reflection.klass.increment_counter(counter_cache_name, record.id)
@reflection.klass.decrement_counter(counter_cache_name, @owner[@reflection.primary_key_name]) if @owner[@reflection.primary_key_name]
end
@target = (AssociationProxy === record ? record.target : record)
- @owner[@reflection.primary_key_name] = record_id(record) unless record.new_record?
+ @owner[@reflection.primary_key_name] = record_id(record) if record.persisted?
@updated = true
end
diff --git a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
index 1fc9aba5cf..da742fa668 100644
--- a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
+++ b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
@@ -34,7 +34,7 @@ module ActiveRecord
end
def insert_record(record, force = true, validate = true)
- if record.new_record?
+ unless record.persisted?
if force
record.save!
else
diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb
index 437c8b1fd6..79c229d9c4 100644
--- a/activerecord/lib/active_record/associations/has_many_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_through_association.rb
@@ -59,7 +59,7 @@ module ActiveRecord
end
def insert_record(record, force = true, validate = true)
- if record.new_record?
+ unless record.persisted?
if force
record.save!
else
@@ -68,8 +68,7 @@ module ActiveRecord
end
through_association = @owner.send(@reflection.through_reflection.name)
- through_record = through_association.create!(construct_join_attributes(record))
- through_association.proxy_target << through_record
+ through_association.create!(construct_join_attributes(record))
end
# TODO - add dependent option support
diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb
index 17901387e9..e6e037441f 100644
--- a/activerecord/lib/active_record/associations/has_one_association.rb
+++ b/activerecord/lib/active_record/associations/has_one_association.rb
@@ -30,18 +30,18 @@ module ActiveRecord
if dependent? && !dont_save
case @reflection.options[:dependent]
when :delete
- @target.delete unless @target.new_record?
+ @target.delete if @target.persisted?
@owner.clear_association_cache
when :destroy
- @target.destroy unless @target.new_record?
+ @target.destroy if @target.persisted?
@owner.clear_association_cache
when :nullify
@target[@reflection.primary_key_name] = nil
- @target.save unless @owner.new_record? || @target.new_record?
+ @target.save if @owner.persisted? && @target.persisted?
end
else
@target[@reflection.primary_key_name] = nil
- @target.save unless @owner.new_record? || @target.new_record?
+ @target.save if @owner.persisted? && @target.persisted?
end
end
@@ -56,7 +56,7 @@ module ActiveRecord
set_inverse_instance(obj, @owner)
@loaded = true
- unless @owner.new_record? or obj.nil? or dont_save
+ unless !@owner.persisted? or obj.nil? or dont_save
return (obj.save ? self : false)
else
return (obj.nil? ? nil : self)
@@ -113,7 +113,7 @@ module ActiveRecord
if replace_existing
replace(record, true)
else
- record[@reflection.primary_key_name] = @owner.id unless @owner.new_record?
+ record[@reflection.primary_key_name] = @owner.id if @owner.persisted?
self.target = record
set_inverse_instance(record, @owner)
end
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 7f28abf464..6e98f7dffb 100644
--- a/activerecord/lib/active_record/associations/has_one_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_one_through_association.rb
@@ -21,7 +21,7 @@ module ActiveRecord
if current_object
new_value ? current_object.update_attributes(construct_join_attributes(new_value)) : current_object.destroy
elsif new_value
- if @owner.new_record?
+ unless @owner.persisted?
self.target = new_value
through_association = @owner.send(:association_instance_get, @reflection.through_reflection.name)
through_association.build(construct_join_attributes(new_value))
diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb
index 82d94b848a..75ae06f5e9 100644
--- a/activerecord/lib/active_record/attribute_methods/primary_key.rb
+++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb
@@ -3,10 +3,11 @@ module ActiveRecord
module PrimaryKey
extend ActiveSupport::Concern
- # Returns this record's primary key value wrapped in an Array
- # or nil if the record is a new_record?
+ # Returns this record's primary key value wrapped in an Array or nil if
+ # the record is not persisted? or has just been destroyed.
def to_key
- new_record? ? nil : [ id ]
+ key = send(self.class.primary_key)
+ [key] if key
end
module ClassMethods
diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb
index 0b89a49896..cb5bc06580 100644
--- a/activerecord/lib/active_record/autosave_association.rb
+++ b/activerecord/lib/active_record/autosave_association.rb
@@ -217,7 +217,7 @@ module ActiveRecord
# Returns whether or not this record has been changed in any way (including whether
# any of its nested autosave associations are likewise changed)
def changed_for_autosave?
- new_record? || changed? || marked_for_destruction? || nested_records_changed_for_autosave?
+ !persisted? || changed? || marked_for_destruction? || nested_records_changed_for_autosave?
end
private
@@ -231,7 +231,7 @@ module ActiveRecord
elsif autosave
association.target.find_all { |record| record.changed_for_autosave? }
else
- association.target.find_all { |record| record.new_record? }
+ association.target.find_all { |record| !record.persisted? }
end
end
@@ -257,7 +257,7 @@ module ActiveRecord
# +reflection+.
def validate_collection_association(reflection)
if association = association_instance_get(reflection.name)
- if records = associated_records_to_validate_or_save(association, new_record?, reflection.options[:autosave])
+ if records = associated_records_to_validate_or_save(association, !persisted?, reflection.options[:autosave])
records.each { |record| association_valid?(reflection, record) }
end
end
@@ -286,7 +286,7 @@ module ActiveRecord
# Is used as a before_save callback to check while saving a collection
# association whether or not the parent was a new record before saving.
def before_save_collection_association
- @new_record_before_save = new_record?
+ @new_record_before_save = !persisted?
true
end
@@ -308,7 +308,7 @@ module ActiveRecord
if autosave && record.marked_for_destruction?
association.destroy(record)
- elsif autosave != false && (@new_record_before_save || record.new_record?)
+ elsif autosave != false && (@new_record_before_save || !record.persisted?)
if autosave
saved = association.send(:insert_record, record, false, false)
else
@@ -343,7 +343,7 @@ module ActiveRecord
association.destroy
else
key = reflection.options[:primary_key] ? send(reflection.options[:primary_key]) : id
- if autosave != false && (new_record? || association.new_record? || association[reflection.primary_key_name] != key || autosave)
+ if autosave != false && (!persisted? || !association.persisted? || association[reflection.primary_key_name] != key || autosave)
association[reflection.primary_key_name] = key
saved = association.save(:validate => !autosave)
raise ActiveRecord::Rollback if !saved && autosave
@@ -363,7 +363,7 @@ module ActiveRecord
if autosave && association.marked_for_destruction?
association.destroy
elsif autosave != false
- saved = association.save(:validate => !autosave) if association.new_record? || autosave
+ saved = association.save(:validate => !autosave) if !association.persisted? || autosave
if association.updated?
association_id = association.send(reflection.options[:primary_key] || :id)
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 06a388cd21..f588475bbf 100644
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -204,7 +204,7 @@ module ActiveRecord #:nodoc:
#
# # No 'Winter' tag exists
# winter = Tag.find_or_initialize_by_name("Winter")
- # winter.new_record? # true
+ # winter.persisted? # false
#
# To find by a subset of the attributes to be used for instantiating a new object, pass a hash instead of
# a list of parameters.
@@ -1368,7 +1368,7 @@ MSG
def initialize(attributes = nil)
@attributes = attributes_from_column_definition
@attributes_cache = {}
- @new_record = true
+ @persisted = false
@readonly = false
@destroyed = false
@marked_for_destruction = false
@@ -1403,7 +1403,7 @@ MSG
clear_aggregation_cache
clear_association_cache
@attributes_cache = {}
- @new_record = true
+ @persisted = false
ensure_proper_type
populate_with_current_scope_attributes
@@ -1422,7 +1422,8 @@ MSG
def init_with(coder)
@attributes = coder['attributes']
@attributes_cache, @previously_changed, @changed_attributes = {}, {}, {}
- @new_record = @readonly = @destroyed = @marked_for_destruction = false
+ @readonly = @destroyed = @marked_for_destruction = false
+ @persisted = true
_run_find_callbacks
_run_initialize_callbacks
end
@@ -1463,7 +1464,7 @@ MSG
# Person.find(5).cache_key # => "people/5-20071224150000" (updated_at available)
def cache_key
case
- when new_record?
+ when !persisted?
"#{self.class.model_name.cache_key}/new"
when timestamp = self[:updated_at]
"#{self.class.model_name.cache_key}/#{id}-#{timestamp.to_s(:number)}"
@@ -1584,8 +1585,9 @@ MSG
# Returns true if the +comparison_object+ is the same object, or is of the same type and has the same id.
def ==(comparison_object)
comparison_object.equal?(self) ||
- (comparison_object.instance_of?(self.class) &&
- comparison_object.id == id && !comparison_object.new_record?)
+ persisted? &&
+ (comparison_object.instance_of?(self.class) &&
+ comparison_object.id == id)
end
# Delegates to ==
@@ -1630,7 +1632,7 @@ MSG
# Returns the contents of the record as a nicely formatted string.
def inspect
attributes_as_nice_string = self.class.column_names.collect { |name|
- if has_attribute?(name) || new_record?
+ if has_attribute?(name) || !persisted?
"#{name}: #{attribute_for_inspect(name)}"
end
}.compact.join(", ")
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 6178130c00..ee9a0af35c 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -50,7 +50,7 @@ module ActiveRecord
# Executes +sql+ statement in the context of this connection using
# +binds+ as the bind substitutes. +name+ is logged along with
# the executed +sql+ statement.
- def exec(sql, name = 'SQL', binds = [])
+ def exec_query(sql, name = 'SQL', binds = [])
end
# Returns the last auto-generated ID from the affected table.
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 7d47d06ae1..ce2352486b 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -326,7 +326,7 @@ module ActiveRecord
@statements.clear
end
- def exec(sql, name = 'SQL', binds = [])
+ def exec_query(sql, name = 'SQL', binds = [])
log(sql, name) do
result = nil
@@ -708,7 +708,7 @@ module ActiveRecord
def select(sql, name = nil, binds = [])
@connection.query_with_result = true
- rows = exec(sql, name, binds).to_a
+ rows = exec_query(sql, name, binds).to_a
@connection.more_results && @connection.next_result # invoking stored procedures with CLIENT_MULTI_RESULTS requires this to tidy up else connection will be dropped
rows
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 58c0f85dc2..ccc5085b84 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -398,7 +398,7 @@ module ActiveRecord
# Set the authorized user for this session
def session_auth=(user)
clear_cache!
- exec "SET SESSION AUTHORIZATION #{user}"
+ exec_query "SET SESSION AUTHORIZATION #{user}"
end
# REFERENTIAL INTEGRITY ====================================
@@ -532,7 +532,7 @@ module ActiveRecord
Arel.sql("$#{current_values.length + 1}")
end
- def exec(sql, name = 'SQL', binds = [])
+ def exec_query(sql, name = 'SQL', binds = [])
return exec_no_cache(sql, name) if binds.empty?
log(sql, name) do
@@ -714,8 +714,8 @@ module ActiveRecord
# Returns the list of all column definitions for a table.
def columns(table_name, name = nil)
# Limit, precision, and scale are all handled by the superclass.
- column_definitions(table_name).collect do |name, type, default, notnull|
- PostgreSQLColumn.new(name, default, type, notnull == 'f')
+ column_definitions(table_name).collect do |column_name, type, default, notnull|
+ PostgreSQLColumn.new(column_name, default, type, notnull == 'f')
end
end
@@ -932,12 +932,12 @@ module ActiveRecord
# requires that the ORDER BY include the distinct column.
#
# distinct("posts.id", "posts.created_at desc")
- def distinct(columns, order_by) #:nodoc:
- return "DISTINCT #{columns}" if order_by.blank?
+ def distinct(columns, orders) #:nodoc:
+ return "DISTINCT #{columns}" if orders.empty?
# Construct a clean list of column names from the ORDER BY clause, removing
# any ASC/DESC modifiers
- order_columns = order_by.split(',').collect { |s| s.split.first }
+ order_columns = orders.collect { |s| s =~ /^(.+)\s+(ASC|DESC)\s*$/i ? $1 : s }
order_columns.delete_if { |c| c.blank? }
order_columns = order_columns.zip((0...order_columns.size).to_a).map { |s,i| "#{s} AS alias_#{i}" }
@@ -1040,7 +1040,7 @@ module ActiveRecord
# Executes a SELECT query and returns the results, performing any data type
# conversions that are required to be performed here instead of in PostgreSQLColumn.
def select(sql, name = nil, binds = [])
- exec(sql, name, binds).to_a
+ exec_query(sql, name, binds).to_a
end
def select_raw(sql, name = nil)
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index fc4d84a4f2..d76fc4103e 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -143,7 +143,7 @@ module ActiveRecord
# DATABASE STATEMENTS ======================================
- def exec(sql, name = nil, binds = [])
+ def exec_query(sql, name = nil, binds = [])
log(sql, name) do
# Don't cache statements without bind values
@@ -186,7 +186,7 @@ module ActiveRecord
alias :create :insert_sql
def select_rows(sql, name = nil)
- exec(sql, name).rows
+ exec_query(sql, name).rows
end
def begin_db_transaction #:nodoc:
@@ -210,7 +210,7 @@ module ActiveRecord
WHERE type = 'table' AND NOT name = 'sqlite_sequence'
SQL
- exec(sql, name).map do |row|
+ exec_query(sql, name).map do |row|
row['name']
end
end
@@ -222,12 +222,12 @@ module ActiveRecord
end
def indexes(table_name, name = nil) #:nodoc:
- exec("PRAGMA index_list(#{quote_table_name(table_name)})", name).map do |row|
+ exec_query("PRAGMA index_list(#{quote_table_name(table_name)})", name).map do |row|
IndexDefinition.new(
table_name,
row['name'],
row['unique'] != 0,
- exec("PRAGMA index_info('#{row['name']}')").map { |col|
+ exec_query("PRAGMA index_info('#{row['name']}')").map { |col|
col['name']
})
end
@@ -241,11 +241,11 @@ module ActiveRecord
end
def remove_index!(table_name, index_name) #:nodoc:
- exec "DROP INDEX #{quote_column_name(index_name)}"
+ exec_query "DROP INDEX #{quote_column_name(index_name)}"
end
def rename_table(name, new_name)
- exec "ALTER TABLE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}"
+ exec_query "ALTER TABLE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}"
end
# See: http://www.sqlite.org/lang_altertable.html
@@ -282,7 +282,7 @@ module ActiveRecord
def change_column_null(table_name, column_name, null, default = nil)
unless null || default.nil?
- exec("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
+ exec_query("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
end
alter_table(table_name) do |definition|
definition[column_name].null = null
@@ -314,7 +314,7 @@ module ActiveRecord
protected
def select(sql, name = nil, binds = []) #:nodoc:
- result = exec(sql, name, binds)
+ result = exec_query(sql, name, binds)
columns = result.columns.map { |column|
column.sub(/^"?\w+"?\./, '')
}
@@ -399,11 +399,11 @@ module ActiveRecord
quoted_columns = columns.map { |col| quote_column_name(col) } * ','
quoted_to = quote_table_name(to)
- exec("SELECT * FROM #{quote_table_name(from)}").each do |row|
+ exec_query("SELECT * FROM #{quote_table_name(from)}").each do |row|
sql = "INSERT INTO #{quoted_to} (#{quoted_columns}) VALUES ("
sql << columns.map {|col| quote row[column_mappings[col]]} * ', '
sql << ')'
- exec sql
+ exec_query sql
end
end
diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb
index b6f87a57b8..bf626301f1 100644
--- a/activerecord/lib/active_record/locking/optimistic.rb
+++ b/activerecord/lib/active_record/locking/optimistic.rb
@@ -109,7 +109,7 @@ module ActiveRecord
def destroy #:nodoc:
return super unless locking_enabled?
- unless new_record?
+ if persisted?
lock_col = self.class.locking_column
previous_value = send(lock_col).to_i
diff --git a/activerecord/lib/active_record/locking/pessimistic.rb b/activerecord/lib/active_record/locking/pessimistic.rb
index 9ad6a2baf7..d900831e13 100644
--- a/activerecord/lib/active_record/locking/pessimistic.rb
+++ b/activerecord/lib/active_record/locking/pessimistic.rb
@@ -47,7 +47,7 @@ module ActiveRecord
# or pass true for "FOR UPDATE" (the default, an exclusive row lock). Returns
# the locked record.
def lock!(lock = true)
- reload(:lock => lock) unless new_record?
+ reload(:lock => lock) if persisted?
self
end
end
diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb
index aca91c907d..0c3392263a 100644
--- a/activerecord/lib/active_record/nested_attributes.rb
+++ b/activerecord/lib/active_record/nested_attributes.rb
@@ -323,7 +323,7 @@ module ActiveRecord
(options[:update_only] || record.id.to_s == attributes['id'].to_s)
assign_to_or_mark_for_destruction(record, attributes, options[:allow_destroy]) unless call_reject_if(association_name, attributes)
- elsif attributes['id']
+ elsif attributes['id'].present?
raise_nested_attributes_record_not_found(association_name, attributes['id'])
elsif !reject_new_record?(association_name, attributes)
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index 707c1a05be..594a2214bb 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -4,7 +4,7 @@ module ActiveRecord
# Returns true if this object hasn't been saved yet -- that is, a record
# for the object doesn't exist in the data store yet; otherwise, returns false.
def new_record?
- @new_record
+ !@persisted
end
# Returns true if this object has been destroyed, otherwise returns false.
@@ -15,7 +15,7 @@ module ActiveRecord
# Returns if the record is persisted, i.e. it's not a new record and it was
# not destroyed.
def persisted?
- !(new_record? || destroyed?)
+ @persisted && !destroyed?
end
# Saves the model.
@@ -94,8 +94,9 @@ module ActiveRecord
became = klass.new
became.instance_variable_set("@attributes", @attributes)
became.instance_variable_set("@attributes_cache", @attributes_cache)
- became.instance_variable_set("@new_record", new_record?)
+ became.instance_variable_set("@persisted", persisted?)
became.instance_variable_set("@destroyed", destroyed?)
+ became.type = klass.name unless self.class.descends_from_active_record?
became
end
@@ -240,7 +241,7 @@ module ActiveRecord
private
def create_or_update
raise ReadOnlyRecord if readonly?
- result = new_record? ? create : update
+ result = persisted? ? update : create
result != false
end
@@ -269,7 +270,7 @@ module ActiveRecord
self.id ||= new_id
- @new_record = false
+ @persisted = true
id
end
diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb
index 868fd6c3ff..dfe255ad7c 100644
--- a/activerecord/lib/active_record/railtie.rb
+++ b/activerecord/lib/active_record/railtie.rb
@@ -14,7 +14,7 @@ module ActiveRecord
config.active_record = ActiveSupport::OrderedOptions.new
config.app_generators.orm :active_record, :migration => true,
- :timestamps => true
+ :timestamps => true
config.app_middleware.insert_after "::ActionDispatch::Callbacks",
"ActiveRecord::QueryCache"
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb
index fe1ef2e2e3..4192456447 100644
--- a/activerecord/lib/active_record/relation/finder_methods.rb
+++ b/activerecord/lib/active_record/relation/finder_methods.rb
@@ -171,14 +171,16 @@ module ActiveRecord
def exists?(id = nil)
id = id.id if ActiveRecord::Base === id
+ relation = select(primary_key).limit(1)
+
case id
when Array, Hash
- where(id).exists?
+ relation = relation.where(id)
else
- relation = select(primary_key).limit(1)
relation = relation.where(primary_key.eq(id)) if id
- relation.first ? true : false
end
+
+ relation.first ? true : false
end
protected
@@ -222,7 +224,7 @@ module ActiveRecord
end
def construct_limited_ids_condition(relation)
- orders = relation.order_values.join(", ")
+ orders = relation.order_values
values = @klass.connection.distinct("#{@klass.connection.quote_table_name @klass.table_name}.#{@klass.primary_key}", orders)
ids_array = relation.select(values).collect {|row| row[@klass.primary_key]}
@@ -298,7 +300,7 @@ module ActiveRecord
unless record
conditions = arel.where_sql
conditions = " [#{conditions}]" if conditions
- raise RecordNotFound, "Couldn't find #{@klass.name} with ID=#{id}#{conditions}"
+ raise RecordNotFound, "Couldn't find #{@klass.name} with #{@klass.primary_key}=#{id}#{conditions}"
end
record
diff --git a/activerecord/lib/active_record/session_store.rb b/activerecord/lib/active_record/session_store.rb
index 3fc596e02a..ba99800fb2 100644
--- a/activerecord/lib/active_record/session_store.rb
+++ b/activerecord/lib/active_record/session_store.rb
@@ -228,7 +228,7 @@ module ActiveRecord
@session_id = attributes[:session_id]
@data = attributes[:data]
@marshaled_data = attributes[:marshaled_data]
- @new_record = @marshaled_data.nil?
+ @persisted = !@marshaled_data.nil?
end
# Lazy-unmarshal session state.
@@ -252,8 +252,8 @@ module ActiveRecord
marshaled_data = self.class.marshal(data)
connect = connection
- if @new_record
- @new_record = false
+ unless @persisted
+ @persisted = true
connect.update <<-end_sql, 'Create session'
INSERT INTO #{table_name} (
#{connect.quote_column_name(session_id_column)},
@@ -272,7 +272,7 @@ module ActiveRecord
end
def destroy
- return if @new_record
+ return unless @persisted
connect = connection
connect.delete <<-end_sql, 'Destroy session'
@@ -321,6 +321,7 @@ module ActiveRecord
if sid = current_session_id(env)
Base.silence do
get_session_model(env, sid).destroy
+ env[SESSION_RECORD_KEY] = nil
end
end
diff --git a/activerecord/lib/active_record/timestamp.rb b/activerecord/lib/active_record/timestamp.rb
index a7583f06cc..230adf6b2b 100644
--- a/activerecord/lib/active_record/timestamp.rb
+++ b/activerecord/lib/active_record/timestamp.rb
@@ -61,7 +61,7 @@ module ActiveRecord
end
def should_record_timestamps?
- record_timestamps && (!partial_updates? || changed?)
+ record_timestamps && (!partial_updates? || changed? || (attributes.keys & self.class.serialized_attributes.keys).present?)
end
def timestamp_attributes_for_update_in_model
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index ab737f0f88..8c94d1a2bc 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -242,7 +242,7 @@ module ActiveRecord
with_transaction_returning_status { super }
end
- # Reset id and @new_record if the transaction rolls back.
+ # Reset id and @persisted if the transaction rolls back.
def rollback_active_record_state!
remember_transaction_record_state
yield
@@ -297,9 +297,9 @@ module ActiveRecord
# Save the new record state and id of a record so it can be restored later if a transaction fails.
def remember_transaction_record_state #:nodoc
@_start_transaction_state ||= {}
- unless @_start_transaction_state.include?(:new_record)
+ unless @_start_transaction_state.include?(:persisted)
@_start_transaction_state[:id] = id if has_attribute?(self.class.primary_key)
- @_start_transaction_state[:new_record] = @new_record
+ @_start_transaction_state[:persisted] = @persisted
end
unless @_start_transaction_state.include?(:destroyed)
@_start_transaction_state[:destroyed] = @destroyed
@@ -323,7 +323,7 @@ module ActiveRecord
restore_state = remove_instance_variable(:@_start_transaction_state)
if restore_state
@attributes = @attributes.dup if @attributes.frozen?
- @new_record = restore_state[:new_record]
+ @persisted = restore_state[:persisted]
@destroyed = restore_state[:destroyed]
if restore_state[:id]
self.id = restore_state[:id]
@@ -345,11 +345,11 @@ module ActiveRecord
def transaction_include_action?(action) #:nodoc
case action
when :create
- transaction_record_state(:new_record)
+ transaction_record_state(:new_record) || !transaction_record_state(:persisted)
when :destroy
destroyed?
when :update
- !(transaction_record_state(:new_record) || destroyed?)
+ !(transaction_record_state(:new_record) || !transaction_record_state(:persisted) || destroyed?)
end
end
end
diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb
index f367315b22..ee45fcdf35 100644
--- a/activerecord/lib/active_record/validations.rb
+++ b/activerecord/lib/active_record/validations.rb
@@ -51,7 +51,7 @@ module ActiveRecord
# Runs all the specified validations and returns true if no errors were added otherwise false.
def valid?(context = nil)
- context ||= (new_record? ? :create : :update)
+ context ||= (persisted? ? :update : :create)
output = super(context)
errors.empty? && output
end
diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb
index cb1d2ae421..3eba7510ac 100644
--- a/activerecord/lib/active_record/validations/uniqueness.rb
+++ b/activerecord/lib/active_record/validations/uniqueness.rb
@@ -31,7 +31,7 @@ module ActiveRecord
relation = relation.where(scope_item => scope_value)
end
- unless record.new_record?
+ if record.persisted?
# TODO : This should be in Arel
relation = relation.where("#{record.class.quoted_table_name}.#{record.class.primary_key} <> ?", record.send(:id))
end
@@ -154,33 +154,25 @@ module ActiveRecord
# | # title!
#
# This could even happen if you use transactions with the 'serializable'
- # isolation level. There are several ways to get around this problem:
+ # isolation level. The best way to work around this problem is to add a unique
+ # index to the database table using
+ # ActiveRecord::ConnectionAdapters::SchemaStatements#add_index. In the
+ # rare case that a race condition occurs, the database will guarantee
+ # the field's uniqueness.
#
- # - By locking the database table before validating, and unlocking it after
- # saving. However, table locking is very expensive, and thus not
- # recommended.
- # - By locking a lock file before validating, and unlocking it after saving.
- # This does not work if you've scaled your Rails application across
- # multiple web servers (because they cannot share lock files, or cannot
- # do that efficiently), and thus not recommended.
- # - Creating a unique index on the field, by using
- # ActiveRecord::ConnectionAdapters::SchemaStatements#add_index. In the
- # rare case that a race condition occurs, the database will guarantee
- # the field's uniqueness.
+ # When the database catches such a duplicate insertion,
+ # ActiveRecord::Base#save will raise an ActiveRecord::StatementInvalid
+ # exception. You can either choose to let this error propagate (which
+ # will result in the default Rails exception page being shown), or you
+ # can catch it and restart the transaction (e.g. by telling the user
+ # that the title already exists, and asking him to re-enter the title).
+ # This technique is also known as optimistic concurrency control:
+ # http://en.wikipedia.org/wiki/Optimistic_concurrency_control
#
- # When the database catches such a duplicate insertion,
- # ActiveRecord::Base#save will raise an ActiveRecord::StatementInvalid
- # exception. You can either choose to let this error propagate (which
- # will result in the default Rails exception page being shown), or you
- # can catch it and restart the transaction (e.g. by telling the user
- # that the title already exists, and asking him to re-enter the title).
- # This technique is also known as optimistic concurrency control:
- # http://en.wikipedia.org/wiki/Optimistic_concurrency_control
- #
- # Active Record currently provides no way to distinguish unique
- # index constraint errors from other types of database errors, so you
- # will have to parse the (database-specific) exception message to detect
- # such a case.
+ # Active Record currently provides no way to distinguish unique
+ # index constraint errors from other types of database errors, so you
+ # will have to parse the (database-specific) exception message to detect
+ # such a case.
#
def validates_uniqueness_of(*attr_names)
validates_with UniquenessValidator, _merge_attributes(attr_names)
diff --git a/activerecord/test/cases/adapters/mysql/connection_test.rb b/activerecord/test/cases/adapters/mysql/connection_test.rb
index 67bd8ec7e0..62ffde558f 100644
--- a/activerecord/test/cases/adapters/mysql/connection_test.rb
+++ b/activerecord/test/cases/adapters/mysql/connection_test.rb
@@ -49,18 +49,18 @@ class MysqlConnectionTest < ActiveRecord::TestCase
end
def test_exec_no_binds
- @connection.exec('drop table if exists ex')
- @connection.exec(<<-eosql)
+ @connection.exec_query('drop table if exists ex')
+ @connection.exec_query(<<-eosql)
CREATE TABLE `ex` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY,
`data` varchar(255))
eosql
- result = @connection.exec('SELECT id, data FROM ex')
+ result = @connection.exec_query('SELECT id, data FROM ex')
assert_equal 0, result.rows.length
assert_equal 2, result.columns.length
assert_equal %w{ id data }, result.columns
- @connection.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
- result = @connection.exec('SELECT id, data FROM ex')
+ @connection.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")')
+ result = @connection.exec_query('SELECT id, data FROM ex')
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
@@ -68,13 +68,13 @@ class MysqlConnectionTest < ActiveRecord::TestCase
end
def test_exec_with_binds
- @connection.exec('drop table if exists ex')
- @connection.exec(<<-eosql)
+ @connection.exec_query('drop table if exists ex')
+ @connection.exec_query(<<-eosql)
CREATE TABLE `ex` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY,
`data` varchar(255))
eosql
- @connection.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
- result = @connection.exec(
+ @connection.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")')
+ result = @connection.exec_query(
'SELECT id, data FROM ex WHERE id = ?', nil, [[nil, 1]])
assert_equal 1, result.rows.length
@@ -84,15 +84,15 @@ class MysqlConnectionTest < ActiveRecord::TestCase
end
def test_exec_typecasts_bind_vals
- @connection.exec('drop table if exists ex')
- @connection.exec(<<-eosql)
+ @connection.exec_query('drop table if exists ex')
+ @connection.exec_query(<<-eosql)
CREATE TABLE `ex` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY,
`data` varchar(255))
eosql
- @connection.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
+ @connection.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")')
column = @connection.columns('ex').find { |col| col.name == 'id' }
- result = @connection.exec(
+ result = @connection.exec_query(
'SELECT id, data FROM ex WHERE id = ?', nil, [[column, '1-fuu']])
assert_equal 1, result.rows.length
diff --git a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
index b0fd2273df..b0a4a4e39d 100644
--- a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
@@ -5,8 +5,8 @@ module ActiveRecord
class PostgreSQLAdapterTest < ActiveRecord::TestCase
def setup
@connection = ActiveRecord::Base.connection
- @connection.exec('drop table if exists ex')
- @connection.exec('create table ex(id serial primary key, data character varying(255))')
+ @connection.exec_query('drop table if exists ex')
+ @connection.exec_query('create table ex(id serial primary key, data character varying(255))')
end
def test_table_alias_length
@@ -16,14 +16,14 @@ module ActiveRecord
end
def test_exec_no_binds
- result = @connection.exec('SELECT id, data FROM ex')
+ result = @connection.exec_query('SELECT id, data FROM ex')
assert_equal 0, result.rows.length
assert_equal 2, result.columns.length
assert_equal %w{ id data }, result.columns
string = @connection.quote('foo')
- @connection.exec("INSERT INTO ex (id, data) VALUES (1, #{string})")
- result = @connection.exec('SELECT id, data FROM ex')
+ @connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})")
+ result = @connection.exec_query('SELECT id, data FROM ex')
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
@@ -32,8 +32,8 @@ module ActiveRecord
def test_exec_with_binds
string = @connection.quote('foo')
- @connection.exec("INSERT INTO ex (id, data) VALUES (1, #{string})")
- result = @connection.exec(
+ @connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})")
+ result = @connection.exec_query(
'SELECT id, data FROM ex WHERE id = $1', nil, [[nil, 1]])
assert_equal 1, result.rows.length
@@ -44,10 +44,10 @@ module ActiveRecord
def test_exec_typecasts_bind_vals
string = @connection.quote('foo')
- @connection.exec("INSERT INTO ex (id, data) VALUES (1, #{string})")
+ @connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})")
column = @connection.columns('ex').find { |col| col.name == 'id' }
- result = @connection.exec(
+ result = @connection.exec_query(
'SELECT id, data FROM ex WHERE id = $1', nil, [[column, '1-fuu']])
assert_equal 1, result.rows.length
diff --git a/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb b/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb
index 881631fb19..d5e1838543 100644
--- a/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb
@@ -55,7 +55,7 @@ class SchemaAuthorizationTest < ActiveRecord::TestCase
set_session_auth
USERS.each do |u|
set_session_auth u
- assert_equal u, @connection.exec("SELECT name FROM #{TABLE_NAME} WHERE id = $1", 'SQL', [[nil, 1]]).first['name']
+ assert_equal u, @connection.exec_query("SELECT name FROM #{TABLE_NAME} WHERE id = $1", 'SQL', [[nil, 1]]).first['name']
set_session_auth
end
end
@@ -67,7 +67,7 @@ class SchemaAuthorizationTest < ActiveRecord::TestCase
USERS.each do |u|
@connection.clear_cache!
set_session_auth u
- assert_equal u, @connection.exec("SELECT name FROM #{TABLE_NAME} WHERE id = $1", 'SQL', [[nil, 1]]).first['name']
+ assert_equal u, @connection.exec_query("SELECT name FROM #{TABLE_NAME} WHERE id = $1", 'SQL', [[nil, 1]]).first['name']
set_session_auth
end
end
diff --git a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
index 973c51f3d7..234696adeb 100644
--- a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
+++ b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
@@ -58,24 +58,24 @@ module ActiveRecord
end
def test_exec_no_binds
- @conn.exec('create table ex(id int, data string)')
- result = @conn.exec('SELECT id, data FROM ex')
+ @conn.exec_query('create table ex(id int, data string)')
+ result = @conn.exec_query('SELECT id, data FROM ex')
assert_equal 0, result.rows.length
assert_equal 2, result.columns.length
assert_equal %w{ id data }, result.columns
- @conn.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
- result = @conn.exec('SELECT id, data FROM ex')
+ @conn.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")')
+ result = @conn.exec_query('SELECT id, data FROM ex')
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
assert_equal [[1, 'foo']], result.rows
end
- def test_exec_with_binds
- @conn.exec('create table ex(id int, data string)')
- @conn.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
- result = @conn.exec(
+ def test_exec_query_with_binds
+ @conn.exec_query('create table ex(id int, data string)')
+ @conn.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")')
+ result = @conn.exec_query(
'SELECT id, data FROM ex WHERE id = ?', nil, [[nil, 1]])
assert_equal 1, result.rows.length
@@ -84,12 +84,12 @@ module ActiveRecord
assert_equal [[1, 'foo']], result.rows
end
- def test_exec_typecasts_bind_vals
- @conn.exec('create table ex(id int, data string)')
- @conn.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
+ def test_exec_query_typecasts_bind_vals
+ @conn.exec_query('create table ex(id int, data string)')
+ @conn.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")')
column = @conn.columns('ex').find { |col| col.name == 'id' }
- result = @conn.exec(
+ result = @conn.exec_query(
'SELECT id, data FROM ex WHERE id = ?', nil, [[column, '1-fuu']])
assert_equal 1, result.rows.length
diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb
index 0fa4328826..1b0c00bd5a 100644
--- a/activerecord/test/cases/associations/belongs_to_associations_test.rb
+++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb
@@ -285,10 +285,10 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
final_cut = Client.new("name" => "Final Cut")
firm = Firm.find(1)
final_cut.firm = firm
- assert final_cut.new_record?
+ assert !final_cut.persisted?
assert final_cut.save
- assert !final_cut.new_record?
- assert !firm.new_record?
+ assert final_cut.persisted?
+ assert firm.persisted?
assert_equal firm, final_cut.firm
assert_equal firm, final_cut.firm(true)
end
@@ -297,10 +297,10 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
final_cut = Client.new("name" => "Final Cut")
firm = Firm.find(1)
final_cut.firm_with_primary_key = firm
- assert final_cut.new_record?
+ assert !final_cut.persisted?
assert final_cut.save
- assert !final_cut.new_record?
- assert !firm.new_record?
+ assert final_cut.persisted?
+ assert firm.persisted?
assert_equal firm, final_cut.firm_with_primary_key
assert_equal firm, final_cut.firm_with_primary_key(true)
end
diff --git a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb
index 271bb92ee8..37c6f354a8 100644
--- a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb
+++ b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb
@@ -137,7 +137,7 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase
end
def test_eager_association_loading_with_multiple_stis_and_order
- author = Author.find(:first, :include => { :posts => [ :special_comments , :very_special_comment ] }, :order => 'authors.name, comments.body, very_special_comments_posts.body', :conditions => 'posts.id = 4')
+ author = Author.find(:first, :include => { :posts => [ :special_comments , :very_special_comment ] }, :order => ['authors.name', 'comments.body', 'very_special_comments_posts.body'], :conditions => 'posts.id = 4')
assert_equal authors(:david), author
assert_no_queries do
author.posts.first.special_comments
diff --git a/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb b/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb
index b124a2bfc3..fb59f63f91 100644
--- a/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb
+++ b/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb
@@ -17,7 +17,7 @@ class EagerLoadIncludeFullStiClassNamesTest < ActiveRecord::TestCase
def generate_test_objects
post = Namespaced::Post.create( :title => 'Great stuff', :body => 'This is not', :author_id => 1 )
- tagging = Tagging.create( :taggable => post )
+ Tagging.create( :taggable => post )
end
def test_class_names
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index 2d8e02e398..66fb5ac1e1 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -323,7 +323,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
def test_eager_with_has_many_through_a_belongs_to_association
author = authors(:mary)
- post = Post.create!(:author => author, :title => "TITLE", :body => "BODY")
+ Post.create!(:author => author, :title => "TITLE", :body => "BODY")
author.author_favorites.create(:favorite_author_id => 1)
author.author_favorites.create(:favorite_author_id => 2)
posts_with_author_favorites = author.posts.find(:all, :include => :author_favorites)
@@ -521,7 +521,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
end
def test_eager_with_inheritance
- posts = SpecialPost.find(:all, :include => [ :comments ])
+ SpecialPost.find(:all, :include => [ :comments ])
end
def test_eager_has_one_with_association_inheritance
@@ -561,16 +561,16 @@ class EagerAssociationTest < ActiveRecord::TestCase
def test_eager_with_invalid_association_reference
assert_raise(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
- post = Post.find(6, :include=> :monkeys )
+ Post.find(6, :include=> :monkeys )
}
assert_raise(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
- post = Post.find(6, :include=>[ :monkeys ])
+ Post.find(6, :include=>[ :monkeys ])
}
assert_raise(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
- post = Post.find(6, :include=>[ 'monkeys' ])
+ Post.find(6, :include=>[ 'monkeys' ])
}
assert_raise(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys, :elephants") {
- post = Post.find(6, :include=>[ :monkeys, :elephants ])
+ Post.find(6, :include=>[ :monkeys, :elephants ])
}
end
@@ -584,8 +584,8 @@ class EagerAssociationTest < ActiveRecord::TestCase
end
def test_limited_eager_with_multiple_order_columns
- assert_equal posts(:thinking, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title), posts.id', :limit => 2, :offset => 1)
- assert_equal posts(:sti_post_and_comments, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC, posts.id', :limit => 2, :offset => 1)
+ assert_equal posts(:thinking, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => ['UPPER(posts.title)', 'posts.id'], :limit => 2, :offset => 1)
+ assert_equal posts(:sti_post_and_comments, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => ['UPPER(posts.title) DESC', 'posts.id'], :limit => 2, :offset => 1)
end
def test_limited_eager_with_numeric_in_association
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 7e070e1746..705550216c 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
@@ -251,10 +251,10 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
no_of_projects = Project.count
aredridel = Developer.new("name" => "Aredridel")
aredridel.projects.concat([Project.find(1), p = Project.new("name" => "Projekt")])
- assert aredridel.new_record?
- assert p.new_record?
+ assert !aredridel.persisted?
+ assert !p.persisted?
assert aredridel.save
- assert !aredridel.new_record?
+ assert aredridel.persisted?
assert_equal no_of_devels+1, Developer.count
assert_equal no_of_projects+1, Project.count
assert_equal 2, aredridel.projects.size
@@ -288,22 +288,22 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
assert_equal devel.projects.last, proj
assert devel.projects.loaded?
- assert proj.new_record?
+ assert !proj.persisted?
devel.save
- assert !proj.new_record?
+ assert proj.persisted?
assert_equal devel.projects.last, proj
assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
end
def test_build_by_new_record
devel = Developer.new(:name => "Marcel", :salary => 75000)
- proj1 = devel.projects.build(:name => "Make bed")
+ devel.projects.build(:name => "Make bed")
proj2 = devel.projects.build(:name => "Lie in it")
assert_equal devel.projects.last, proj2
- assert proj2.new_record?
+ assert !proj2.persisted?
devel.save
- assert !devel.new_record?
- assert !proj2.new_record?
+ assert devel.persisted?
+ assert proj2.persisted?
assert_equal devel.projects.last, proj2
assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
end
@@ -316,19 +316,19 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
assert_equal devel.projects.last, proj
assert !devel.projects.loaded?
- assert !proj.new_record?
+ assert proj.persisted?
assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
end
def test_create_by_new_record
devel = Developer.new(:name => "Marcel", :salary => 75000)
- proj1 = devel.projects.build(:name => "Make bed")
+ devel.projects.build(:name => "Make bed")
proj2 = devel.projects.build(:name => "Lie in it")
assert_equal devel.projects.last, proj2
- assert proj2.new_record?
+ assert !proj2.persisted?
devel.save
- assert !devel.new_record?
- assert !proj2.new_record?
+ assert devel.persisted?
+ assert proj2.persisted?
assert_equal devel.projects.last, proj2
assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
end
@@ -343,7 +343,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
# in Oracle '' is saved as null therefore need to save ' ' in not null column
another_post = categories(:general).post_with_conditions.create(:body => ' ')
- assert !another_post.new_record?
+ assert another_post.persisted?
assert_equal 'Yet Another Testing Title', another_post.title
end
@@ -559,8 +559,6 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
def test_dynamic_find_should_respect_association_order
# Developers are ordered 'name DESC, id DESC'
- low_id_jamis = developers(:jamis)
- middle_id_jamis = developers(:poor_jamis)
high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
assert_equal high_id_jamis, projects(:active_record).developers.find(:first, :conditions => "name = 'Jamis'")
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index c9f00fd737..ecfc769f3a 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -66,6 +66,17 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal 'exotic', bulb.name
end
+ def test_no_sql_should_be_fired_if_association_already_loaded
+ car = Car.create(:name => 'honda')
+ bulb = car.bulbs.create
+ bulbs = Car.first.bulbs
+ bulbs.inspect # to load all instances of bulbs
+ assert_no_queries do
+ bulbs.first()
+ bulbs.first({})
+ end
+ end
+
def test_create_resets_cached_counters
person = Person.create!(:first_name => 'tenderlove')
post = Post.first
@@ -73,7 +84,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal [], person.readers
assert_nil person.readers.find_by_post_id(post.id)
- reader = person.readers.create(:post_id => post.id)
+ person.readers.create(:post_id => post.id)
assert_equal 1, person.readers.count
assert_equal 1, person.readers.length
@@ -88,7 +99,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal [], person.readers
assert_nil person.readers.find_by_post_id(post.id)
- reader = person.readers.find_or_create_by_post_id(post.id)
+ person.readers.find_or_create_by_post_id(post.id)
assert_equal 1, person.readers.count
assert_equal 1, person.readers.length
@@ -187,7 +198,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
another = author.posts.find_or_create_by_title_and_body("Another Post", "This is the Body")
assert_equal number_of_posts + 1, Post.count
assert_equal another, author.posts.find_or_create_by_title_and_body("Another Post", "This is the Body")
- assert !another.new_record?
+ assert another.persisted?
end
def test_cant_save_has_many_readonly_association
@@ -402,7 +413,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_adding_using_create
first_firm = companies(:first_firm)
assert_equal 2, first_firm.plain_clients.size
- natural = first_firm.plain_clients.create(:name => "Natural Company")
+ first_firm.plain_clients.create(:name => "Natural Company")
assert_equal 3, first_firm.plain_clients.length
assert_equal 3, first_firm.plain_clients.size
end
@@ -453,7 +464,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert !company.clients_of_firm.loaded?
assert_equal "Another Client", new_client.name
- assert new_client.new_record?
+ assert !new_client.persisted?
assert_equal new_client, company.clients_of_firm.last
end
@@ -483,7 +494,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
def test_build_followed_by_save_does_not_load_target
- new_client = companies(:first_firm).clients_of_firm.build("name" => "Another Client")
+ companies(:first_firm).clients_of_firm.build("name" => "Another Client")
assert companies(:first_firm).save
assert !companies(:first_firm).clients_of_firm.loaded?
end
@@ -508,7 +519,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert !company.clients_of_firm.loaded?
assert_equal "Another Client", new_client.name
- assert new_client.new_record?
+ assert !new_client.persisted?
assert_equal new_client, company.clients_of_firm.last
end
@@ -543,7 +554,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_create
force_signal37_to_load_all_clients_of_firm
new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client")
- assert !new_client.new_record?
+ assert new_client.persisted?
assert_equal new_client, companies(:first_firm).clients_of_firm.last
assert_equal new_client, companies(:first_firm).clients_of_firm(true).last
end
@@ -554,7 +565,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
def test_create_followed_by_save_does_not_load_target
- new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client")
+ companies(:first_firm).clients_of_firm.create("name" => "Another Client")
assert companies(:first_firm).save
assert !companies(:first_firm).clients_of_firm.loaded?
end
@@ -563,7 +574,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
the_client = companies(:first_firm).clients.find_or_initialize_by_name("Yet another client")
assert_equal companies(:first_firm).id, the_client.firm_id
assert_equal "Yet another client", the_client.name
- assert the_client.new_record?
+ assert !the_client.persisted?
end
def test_find_or_create_updates_size
@@ -752,7 +763,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
another_ms_client = companies(:first_firm).clients_like_ms_with_hash_conditions.create
- assert !another_ms_client.new_record?
+ assert another_ms_client.persisted?
assert_equal 'Microsoft', another_ms_client.name
end
@@ -852,7 +863,6 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_dependence_for_associations_with_hash_condition
david = authors(:david)
- post = posts(:thinking).id
assert_difference('Post.count', -1) { assert david.destroy }
end
@@ -872,7 +882,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_three_levels_of_dependence
topic = Topic.create "title" => "neat and simple"
reply = topic.replies.create "title" => "neat and simple", "content" => "still digging it"
- silly_reply = reply.replies.create "title" => "neat and simple", "content" => "ain't complaining"
+ reply.replies.create "title" => "neat and simple", "content" => "ain't complaining"
assert_nothing_raised { topic.destroy }
end
@@ -897,7 +907,6 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_depends_and_nullify
num_accounts = Account.count
- num_companies = Company.count
core = companies(:rails_core)
assert_equal accounts(:rails_core_account), core.account
@@ -914,7 +923,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_restrict
firm = RestrictedFirm.new(:name => 'restrict')
firm.save!
- child_firm = firm.companies.create(:name => 'child')
+ firm.companies.create(:name => 'child')
assert !firm.companies.empty?
assert_raise(ActiveRecord::DeleteRestrictionError) { firm.destroy }
end
diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb
index 4b9f49f1ec..94e1eb8c89 100644
--- a/activerecord/test/cases/associations/has_many_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb
@@ -449,4 +449,11 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
comment = post.comments.build
assert author.comments.include?(comment)
end
+
+ def test_size_of_through_association_should_increase_correctly_when_has_many_association_is_added
+ post = posts(:thinking)
+ readers = post.readers.size
+ post.people << people(:michael)
+ assert_equal readers + 1, post.readers.size
+ end
end
diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb
index b522be3fe0..6fbeff8aa9 100644
--- a/activerecord/test/cases/associations/has_one_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_associations_test.rb
@@ -268,7 +268,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
def test_assignment_before_child_saved
firm = Firm.find(1)
firm.account = a = Account.new("credit_limit" => 1000)
- assert !a.new_record?
+ assert a.persisted?
assert_equal a, firm.account
assert_equal a, firm.account
assert_equal a, firm.account(true)
@@ -323,7 +323,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
def test_create_respects_hash_condition
account = companies(:first_firm).create_account_limit_500_with_hash_conditions
- assert !account.new_record?
+ assert account.persisted?
assert_equal 500, account.credit_limit
end
diff --git a/activerecord/test/cases/associations/join_model_test.rb b/activerecord/test/cases/associations/join_model_test.rb
index 7a22ce4dad..96edcfbb35 100644
--- a/activerecord/test/cases/associations/join_model_test.rb
+++ b/activerecord/test/cases/associations/join_model_test.rb
@@ -450,11 +450,11 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
new_tag = Tag.new(:name => "new")
saved_post.tags << new_tag
- assert !new_tag.new_record? #consistent with habtm!
- assert !saved_post.new_record?
+ assert new_tag.persisted? #consistent with habtm!
+ assert saved_post.persisted?
assert saved_post.tags.include?(new_tag)
- assert !new_tag.new_record?
+ assert new_tag.persisted?
assert saved_post.reload.tags(true).include?(new_tag)
@@ -462,16 +462,16 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
saved_tag = tags(:general)
new_post.tags << saved_tag
- assert new_post.new_record?
- assert !saved_tag.new_record?
+ assert !new_post.persisted?
+ assert saved_tag.persisted?
assert new_post.tags.include?(saved_tag)
new_post.save!
- assert !new_post.new_record?
+ assert new_post.persisted?
assert new_post.reload.tags(true).include?(saved_tag)
- assert posts(:thinking).tags.build.new_record?
- assert posts(:thinking).tags.new.new_record?
+ assert !posts(:thinking).tags.build.persisted?
+ assert !posts(:thinking).tags.new.persisted?
end
def test_create_associate_when_adding_to_has_many_through
diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb
index 89be94c81f..459f9fa55c 100644
--- a/activerecord/test/cases/autosave_association_test.rb
+++ b/activerecord/test/cases/autosave_association_test.rb
@@ -83,7 +83,7 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
assert !firm.build_account_using_primary_key.valid?
assert firm.save
- assert firm.account_using_primary_key.new_record?
+ assert !firm.account_using_primary_key.persisted?
end
def test_save_fails_for_invalid_has_one
@@ -114,10 +114,10 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
account = firm.account.build("credit_limit" => 1000)
assert_equal account, firm.account
- assert account.new_record?
+ assert !account.persisted?
assert firm.save
assert_equal account, firm.account
- assert !account.new_record?
+ assert account.persisted?
end
def test_build_before_either_saved
@@ -125,16 +125,16 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
firm.account = account = Account.new("credit_limit" => 1000)
assert_equal account, firm.account
- assert account.new_record?
+ assert !account.persisted?
assert firm.save
assert_equal account, firm.account
- assert !account.new_record?
+ assert account.persisted?
end
def test_assignment_before_parent_saved
firm = Firm.new("name" => "GlobalMegaCorp")
firm.account = a = Account.find(1)
- assert firm.new_record?
+ assert !firm.persisted?
assert_equal a, firm.account
assert firm.save
assert_equal a, firm.account
@@ -144,12 +144,12 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
def test_assignment_before_either_saved
firm = Firm.new("name" => "GlobalMegaCorp")
firm.account = a = Account.new("credit_limit" => 1000)
- assert firm.new_record?
- assert a.new_record?
+ assert !firm.persisted?
+ assert !a.persisted?
assert_equal a, firm.account
assert firm.save
- assert !firm.new_record?
- assert !a.new_record?
+ assert firm.persisted?
+ assert a.persisted?
assert_equal a, firm.account
assert_equal a, firm.account(true)
end
@@ -203,7 +203,7 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test
assert !client.firm.valid?
assert client.save
- assert client.firm.new_record?
+ assert !client.firm.persisted?
end
def test_save_fails_for_invalid_belongs_to
@@ -232,10 +232,10 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test
apple = Firm.new("name" => "Apple")
client.firm = apple
assert_equal apple, client.firm
- assert apple.new_record?
+ assert !apple.persisted?
assert client.save
assert apple.save
- assert !apple.new_record?
+ assert apple.persisted?
assert_equal apple, client.firm
assert_equal apple, client.firm(true)
end
@@ -244,11 +244,11 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test
final_cut = Client.new("name" => "Final Cut")
apple = Firm.new("name" => "Apple")
final_cut.firm = apple
- assert final_cut.new_record?
- assert apple.new_record?
+ assert !final_cut.persisted?
+ assert !apple.persisted?
assert final_cut.save
- assert !final_cut.new_record?
- assert !apple.new_record?
+ assert final_cut.persisted?
+ assert apple.persisted?
assert_equal apple, final_cut.firm
assert_equal apple, final_cut.firm(true)
end
@@ -348,10 +348,10 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
def test_invalid_adding
firm = Firm.find(1)
assert !(firm.clients_of_firm << c = Client.new)
- assert c.new_record?
+ assert !c.persisted?
assert !firm.valid?
assert !firm.save
- assert c.new_record?
+ assert !c.persisted?
end
def test_invalid_adding_before_save
@@ -359,12 +359,12 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
no_of_clients = Client.count
new_firm = Firm.new("name" => "A New Firm, Inc")
new_firm.clients_of_firm.concat([c = Client.new, Client.new("name" => "Apple")])
- assert c.new_record?
+ assert !c.persisted?
assert !c.valid?
assert !new_firm.valid?
assert !new_firm.save
- assert c.new_record?
- assert new_firm.new_record?
+ assert !c.persisted?
+ assert !new_firm.persisted?
end
def test_invalid_adding_with_validate_false
@@ -375,7 +375,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
assert firm.valid?
assert !client.valid?
assert firm.save
- assert client.new_record?
+ assert !client.persisted?
end
def test_valid_adding_with_validate_false
@@ -386,22 +386,22 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
assert firm.valid?
assert client.valid?
- assert client.new_record?
+ assert !client.persisted?
firm.unvalidated_clients_of_firm << client
assert firm.save
- assert !client.new_record?
+ assert client.persisted?
assert_equal no_of_clients + 1, Client.count
end
def test_invalid_build
new_client = companies(:first_firm).clients_of_firm.build
- assert new_client.new_record?
+ assert !new_client.persisted?
assert !new_client.valid?
assert_equal new_client, companies(:first_firm).clients_of_firm.last
assert !companies(:first_firm).save
- assert new_client.new_record?
+ assert !new_client.persisted?
assert_equal 1, companies(:first_firm).clients_of_firm(true).size
end
@@ -420,8 +420,8 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
assert_equal no_of_firms, Firm.count # Firm was not saved to database.
assert_equal no_of_clients, Client.count # Clients were not saved to database.
assert new_firm.save
- assert !new_firm.new_record?
- assert !c.new_record?
+ assert new_firm.persisted?
+ assert c.persisted?
assert_equal new_firm, c.firm
assert_equal no_of_firms + 1, Firm.count # Firm was saved to database.
assert_equal no_of_clients + 2, Client.count # Clients were saved to database.
@@ -455,7 +455,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
company.name += '-changed'
assert_queries(2) { assert company.save }
- assert !new_client.new_record?
+ assert new_client.persisted?
assert_equal 2, company.clients_of_firm(true).size
end
@@ -475,7 +475,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
company.name += '-changed'
assert_queries(2) { assert company.save }
- assert !new_client.new_record?
+ assert new_client.persisted?
assert_equal 2, company.clients_of_firm(true).size
end
@@ -507,62 +507,62 @@ class TestDefaultAutosaveAssociationOnNewRecord < ActiveRecord::TestCase
new_account = Account.new("credit_limit" => 1000)
new_firm = Firm.new("name" => "some firm")
- assert new_firm.new_record?
+ assert !new_firm.persisted?
new_account.firm = new_firm
new_account.save!
- assert !new_firm.new_record?
+ assert new_firm.persisted?
new_account = Account.new("credit_limit" => 1000)
new_autosaved_firm = Firm.new("name" => "some firm")
- assert new_autosaved_firm.new_record?
+ assert !new_autosaved_firm.persisted?
new_account.unautosaved_firm = new_autosaved_firm
new_account.save!
- assert new_autosaved_firm.new_record?
+ assert !new_autosaved_firm.persisted?
end
def test_autosave_new_record_on_has_one_can_be_disabled_per_relationship
firm = Firm.new("name" => "some firm")
account = Account.new("credit_limit" => 1000)
- assert account.new_record?
+ assert !account.persisted?
firm.account = account
firm.save!
- assert !account.new_record?
+ assert account.persisted?
firm = Firm.new("name" => "some firm")
account = Account.new("credit_limit" => 1000)
firm.unautosaved_account = account
- assert account.new_record?
+ assert !account.persisted?
firm.unautosaved_account = account
firm.save!
- assert account.new_record?
+ assert !account.persisted?
end
def test_autosave_new_record_on_has_many_can_be_disabled_per_relationship
firm = Firm.new("name" => "some firm")
account = Account.new("credit_limit" => 1000)
- assert account.new_record?
+ assert !account.persisted?
firm.accounts << account
firm.save!
- assert !account.new_record?
+ assert account.persisted?
firm = Firm.new("name" => "some firm")
account = Account.new("credit_limit" => 1000)
- assert account.new_record?
+ assert !account.persisted?
firm.unautosaved_accounts << account
firm.save!
- assert account.new_record?
+ assert !account.persisted?
end
end
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index e63e1fbe09..9f2b0c9c86 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -656,8 +656,8 @@ class BasicsTest < ActiveRecord::TestCase
end
def test_new_record_returns_boolean
- assert_equal true, Topic.new.new_record?
- assert_equal false, Topic.find(1).new_record?
+ assert_equal false, Topic.new.persisted?
+ assert_equal true, Topic.find(1).persisted?
end
def test_clone
@@ -665,7 +665,7 @@ class BasicsTest < ActiveRecord::TestCase
cloned_topic = nil
assert_nothing_raised { cloned_topic = topic.clone }
assert_equal topic.title, cloned_topic.title
- assert cloned_topic.new_record?
+ assert !cloned_topic.persisted?
# test if the attributes have been cloned
topic.title = "a"
@@ -684,7 +684,7 @@ class BasicsTest < ActiveRecord::TestCase
# test if saved clone object differs from original
cloned_topic.save
- assert !cloned_topic.new_record?
+ assert cloned_topic.persisted?
assert_not_equal cloned_topic.id, topic.id
cloned_topic.reload
@@ -700,7 +700,7 @@ class BasicsTest < ActiveRecord::TestCase
assert_nothing_raised { clone = dev.clone }
assert_kind_of DeveloperSalary, clone.salary
assert_equal dev.salary.amount, clone.salary.amount
- assert clone.new_record?
+ assert !clone.persisted?
# test if the attributes have been cloned
original_amount = clone.salary.amount
@@ -708,7 +708,7 @@ class BasicsTest < ActiveRecord::TestCase
assert_equal original_amount, clone.salary.amount
assert clone.save
- assert !clone.new_record?
+ assert clone.persisted?
assert_not_equal clone.id, dev.id
end
@@ -1353,7 +1353,7 @@ class BasicsTest < ActiveRecord::TestCase
def test_inspect_instance
topic = topics(:first)
- assert_equal %(#<Topic id: 1, title: "The First Topic", author_name: "David", author_email_address: "david@loudthinking.com", written_on: "#{topic.written_on.to_s(:db)}", bonus_time: "#{topic.bonus_time.to_s(:db)}", last_read: "#{topic.last_read.to_s(:db)}", content: "Have a nice day", approved: false, replies_count: 1, parent_id: nil, parent_title: nil, type: nil, group: nil>), topic.inspect
+ assert_equal %(#<Topic id: 1, title: "The First Topic", author_name: "David", author_email_address: "david@loudthinking.com", written_on: "#{topic.written_on.to_s(:db)}", bonus_time: "#{topic.bonus_time.to_s(:db)}", last_read: "#{topic.last_read.to_s(:db)}", content: "Have a nice day", approved: false, replies_count: 1, parent_id: nil, parent_title: nil, type: nil, group: nil, created_at: "#{topic.created_at.to_s(:db)}", updated_at: "#{topic.updated_at.to_s(:db)}">), topic.inspect
end
def test_inspect_new_instance
diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb
index bde93d1c85..b1a54af192 100644
--- a/activerecord/test/cases/dirty_test.rb
+++ b/activerecord/test/cases/dirty_test.rb
@@ -395,6 +395,20 @@ class DirtyTest < ActiveRecord::TestCase
end
end
+ def test_save_always_should_update_timestamps_when_serialized_attributes_are_present
+ with_partial_updates(Topic) do
+ topic = Topic.create!(:content => {:a => "a"})
+ topic.save!
+
+ updated_at = topic.updated_at
+ topic.content[:hello] = 'world'
+ topic.save!
+
+ assert_not_equal updated_at, topic.updated_at
+ assert_equal 'world', topic.content[:hello]
+ end
+ end
+
def test_save_should_not_save_serialized_attribute_with_partial_updates_if_not_present
with_partial_updates(Topic) do
Topic.create!(:author_name => 'Bill', :content => {:a => "a"})
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index c058196078..39ce47d9d6 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -10,6 +10,7 @@ require 'models/entrant'
require 'models/project'
require 'models/developer'
require 'models/customer'
+require 'models/toy'
class FinderTest < ActiveRecord::TestCase
fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :comments, :accounts, :authors, :customers, :categories, :categorizations
@@ -726,7 +727,7 @@ class FinderTest < ActiveRecord::TestCase
sig38 = Company.find_or_create_by_name("38signals")
assert_equal number_of_companies + 1, Company.count
assert_equal sig38, Company.find_or_create_by_name("38signals")
- assert !sig38.new_record?
+ assert sig38.persisted?
end
def test_find_or_create_from_two_attributes
@@ -734,7 +735,7 @@ class FinderTest < ActiveRecord::TestCase
another = Topic.find_or_create_by_title_and_author_name("Another topic","John")
assert_equal number_of_topics + 1, Topic.count
assert_equal another, Topic.find_or_create_by_title_and_author_name("Another topic", "John")
- assert !another.new_record?
+ assert another.persisted?
end
def test_find_or_create_from_two_attributes_with_one_being_an_aggregate
@@ -742,7 +743,7 @@ class FinderTest < ActiveRecord::TestCase
created_customer = Customer.find_or_create_by_balance_and_name(Money.new(123), "Elizabeth")
assert_equal number_of_customers + 1, Customer.count
assert_equal created_customer, Customer.find_or_create_by_balance(Money.new(123), "Elizabeth")
- assert !created_customer.new_record?
+ assert created_customer.persisted?
end
def test_find_or_create_from_one_attribute_and_hash
@@ -750,7 +751,7 @@ class FinderTest < ActiveRecord::TestCase
sig38 = Company.find_or_create_by_name({:name => "38signals", :firm_id => 17, :client_of => 23})
assert_equal number_of_companies + 1, Company.count
assert_equal sig38, Company.find_or_create_by_name({:name => "38signals", :firm_id => 17, :client_of => 23})
- assert !sig38.new_record?
+ assert sig38.persisted?
assert_equal "38signals", sig38.name
assert_equal 17, sig38.firm_id
assert_equal 23, sig38.client_of
@@ -761,7 +762,7 @@ class FinderTest < ActiveRecord::TestCase
created_customer = Customer.find_or_create_by_balance(Money.new(123))
assert_equal number_of_customers + 1, Customer.count
assert_equal created_customer, Customer.find_or_create_by_balance(Money.new(123))
- assert !created_customer.new_record?
+ assert created_customer.persisted?
end
def test_find_or_create_from_one_aggregate_attribute_and_hash
@@ -771,7 +772,7 @@ class FinderTest < ActiveRecord::TestCase
created_customer = Customer.find_or_create_by_balance({:balance => balance, :name => name})
assert_equal number_of_customers + 1, Customer.count
assert_equal created_customer, Customer.find_or_create_by_balance({:balance => balance, :name => name})
- assert !created_customer.new_record?
+ assert created_customer.persisted?
assert_equal balance, created_customer.balance
assert_equal name, created_customer.name
end
@@ -779,13 +780,13 @@ class FinderTest < ActiveRecord::TestCase
def test_find_or_initialize_from_one_attribute
sig38 = Company.find_or_initialize_by_name("38signals")
assert_equal "38signals", sig38.name
- assert sig38.new_record?
+ assert !sig38.persisted?
end
def test_find_or_initialize_from_one_aggregate_attribute
new_customer = Customer.find_or_initialize_by_balance(Money.new(123))
assert_equal 123, new_customer.balance.amount
- assert new_customer.new_record?
+ assert !new_customer.persisted?
end
def test_find_or_initialize_from_one_attribute_should_not_set_attribute_even_when_protected
@@ -793,7 +794,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_not_equal 1000, c.rating
assert c.valid?
- assert c.new_record?
+ assert !c.persisted?
end
def test_find_or_create_from_one_attribute_should_not_set_attribute_even_when_protected
@@ -801,7 +802,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_not_equal 1000, c.rating
assert c.valid?
- assert !c.new_record?
+ assert c.persisted?
end
def test_find_or_initialize_from_one_attribute_should_set_attribute_even_when_protected
@@ -809,7 +810,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000, c.rating
assert c.valid?
- assert c.new_record?
+ assert !c.persisted?
end
def test_find_or_create_from_one_attribute_should_set_attribute_even_when_protected
@@ -817,7 +818,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000, c.rating
assert c.valid?
- assert !c.new_record?
+ assert c.persisted?
end
def test_find_or_initialize_from_one_attribute_should_set_attribute_even_when_protected_and_also_set_the_hash
@@ -825,7 +826,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000, c.rating
assert c.valid?
- assert c.new_record?
+ assert !c.persisted?
end
def test_find_or_create_from_one_attribute_should_set_attribute_even_when_protected_and_also_set_the_hash
@@ -833,7 +834,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000, c.rating
assert c.valid?
- assert !c.new_record?
+ assert c.persisted?
end
def test_find_or_initialize_should_set_protected_attributes_if_given_as_block
@@ -841,7 +842,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000.to_f, c.rating.to_f
assert c.valid?
- assert c.new_record?
+ assert !c.persisted?
end
def test_find_or_create_should_set_protected_attributes_if_given_as_block
@@ -849,7 +850,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000.to_f, c.rating.to_f
assert c.valid?
- assert !c.new_record?
+ assert c.persisted?
end
def test_find_or_create_should_work_with_block_on_first_call
@@ -860,21 +861,21 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000.to_f, c.rating.to_f
assert c.valid?
- assert !c.new_record?
+ assert c.persisted?
end
def test_find_or_initialize_from_two_attributes
another = Topic.find_or_initialize_by_title_and_author_name("Another topic","John")
assert_equal "Another topic", another.title
assert_equal "John", another.author_name
- assert another.new_record?
+ assert !another.persisted?
end
def test_find_or_initialize_from_one_aggregate_attribute_and_one_not
new_customer = Customer.find_or_initialize_by_balance_and_name(Money.new(123), "Elizabeth")
assert_equal 123, new_customer.balance.amount
assert_equal "Elizabeth", new_customer.name
- assert new_customer.new_record?
+ assert !new_customer.persisted?
end
def test_find_or_initialize_from_one_attribute_and_hash
@@ -882,7 +883,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "38signals", sig38.name
assert_equal 17, sig38.firm_id
assert_equal 23, sig38.client_of
- assert sig38.new_record?
+ assert !sig38.persisted?
end
def test_find_or_initialize_from_one_aggregate_attribute_and_hash
@@ -891,7 +892,7 @@ class FinderTest < ActiveRecord::TestCase
new_customer = Customer.find_or_initialize_by_balance({:balance => balance, :name => name})
assert_equal balance, new_customer.balance
assert_equal name, new_customer.name
- assert new_customer.new_record?
+ assert !new_customer.persisted?
end
def test_find_with_bad_sql
@@ -1010,6 +1011,15 @@ class FinderTest < ActiveRecord::TestCase
end
end
+ def test_find_one_message_with_custom_primary_key
+ Toy.set_primary_key :name
+ begin
+ Toy.find 'Hello World!'
+ rescue ActiveRecord::RecordNotFound => e
+ assert_equal 'Couldn\'t find Toy with name=Hello World!', e.message
+ end
+ end
+
protected
def bind(statement, *vars)
if vars.first.is_a?(Hash)
diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb
index f6ef155d66..52f26b71f5 100644
--- a/activerecord/test/cases/helper.rb
+++ b/activerecord/test/cases/helper.rb
@@ -48,6 +48,10 @@ end
ActiveRecord::Base.connection.class.class_eval do
IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /SHOW FIELDS/]
+ # FIXME: this needs to be refactored so specific database can add their own
+ # ignored SQL. This ignored SQL is for Oracle.
+ IGNORED_SQL.concat [/^select .*nextval/i, /^SAVEPOINT/, /^ROLLBACK TO/, /^\s*select .* from ((all|user)_tab_columns|(all|user)_triggers|(all|user)_constraints)/im]
+
def execute_with_query_record(sql, name = nil, &block)
$queries_executed ||= []
$queries_executed << sql unless IGNORED_SQL.any? { |r| sql =~ r }
@@ -56,13 +60,13 @@ ActiveRecord::Base.connection.class.class_eval do
alias_method_chain :execute, :query_record
- def exec_with_query_record(sql, name = nil, binds = [], &block)
+ def exec_query_with_query_record(sql, name = nil, binds = [], &block)
$queries_executed ||= []
$queries_executed << sql unless IGNORED_SQL.any? { |r| sql =~ r }
- exec_without_query_record(sql, name, binds, &block)
+ exec_query_without_query_record(sql, name, binds, &block)
end
- alias_method_chain :exec, :query_record
+ alias_method_chain :exec_query, :query_record
end
ActiveRecord::Base.connection.class.class_eval {
diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb
index 60f89da95e..92af53d56f 100644
--- a/activerecord/test/cases/nested_attributes_test.rb
+++ b/activerecord/test/cases/nested_attributes_test.rb
@@ -139,6 +139,14 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase
assert_equal 'gardening', interest.reload.topic
end
+ def test_reject_if_with_blank_nested_attributes_id
+ # When using a select list to choose an existing 'ship' id, with :include_blank => true
+ Pirate.accepts_nested_attributes_for :ship, :reject_if => proc {|attributes| attributes[:id].blank? }
+
+ pirate = Pirate.new(:catchphrase => "Stop wastin' me time")
+ pirate.ship_attributes = { :id => "" }
+ assert_nothing_raised(ActiveRecord::RecordNotFound) { pirate.save! }
+ end
end
class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
@@ -163,7 +171,7 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
@ship.destroy
@pirate.reload.ship_attributes = { :name => 'Davy Jones Gold Dagger' }
- assert @pirate.ship.new_record?
+ assert !@pirate.ship.persisted?
assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name
end
@@ -184,7 +192,7 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
def test_should_replace_an_existing_record_if_there_is_no_id
@pirate.reload.ship_attributes = { :name => 'Davy Jones Gold Dagger' }
- assert @pirate.ship.new_record?
+ assert !@pirate.ship.persisted?
assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name
assert_equal 'Nights Dirty Lightning', @ship.name
end
@@ -256,7 +264,7 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
def test_should_also_work_with_a_HashWithIndifferentAccess
@pirate.ship_attributes = HashWithIndifferentAccess.new(:id => @ship.id, :name => 'Davy Jones Gold Dagger')
- assert !@pirate.ship.new_record?
+ assert @pirate.ship.persisted?
assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name
end
@@ -348,7 +356,7 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase
@pirate.destroy
@ship.reload.pirate_attributes = { :catchphrase => 'Arr' }
- assert @ship.pirate.new_record?
+ assert !@ship.pirate.persisted?
assert_equal 'Arr', @ship.pirate.catchphrase
end
@@ -369,7 +377,7 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase
def test_should_replace_an_existing_record_if_there_is_no_id
@ship.reload.pirate_attributes = { :catchphrase => 'Arr' }
- assert @ship.pirate.new_record?
+ assert !@ship.pirate.persisted?
assert_equal 'Arr', @ship.pirate.catchphrase
assert_equal 'Aye', @pirate.catchphrase
end
@@ -458,7 +466,7 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase
@pirate.delete
@ship.reload.attributes = { :update_only_pirate_attributes => { :catchphrase => 'Arr' } }
- assert @ship.update_only_pirate.new_record?
+ assert !@ship.update_only_pirate.persisted?
end
def test_should_update_existing_when_update_only_is_true_and_no_id_is_given
@@ -596,10 +604,10 @@ module NestedAttributesOnACollectionAssociationTests
association_getter => { 'foo' => { :name => 'Grace OMalley' }, 'bar' => { :name => 'Privateers Greed' }}
}
- assert @pirate.send(@association_name).first.new_record?
+ assert !@pirate.send(@association_name).first.persisted?
assert_equal 'Grace OMalley', @pirate.send(@association_name).first.name
- assert @pirate.send(@association_name).last.new_record?
+ assert !@pirate.send(@association_name).last.persisted?
assert_equal 'Privateers Greed', @pirate.send(@association_name).last.name
end
diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb
index ffe6fb95b8..07262f56be 100644
--- a/activerecord/test/cases/persistence_test.rb
+++ b/activerecord/test/cases/persistence_test.rb
@@ -241,6 +241,15 @@ class PersistencesTest < ActiveRecord::TestCase
assert_nothing_raised { minimalistic.save }
end
+ def test_update_sti_type
+ assert_instance_of Reply, topics(:second)
+
+ topic = topics(:second).becomes(Topic)
+ assert_instance_of Topic, topic
+ topic.save!
+ assert_instance_of Topic, Topic.find(topic.id)
+ end
+
def test_delete
topic = Topic.find(1)
assert_equal topic, topic.delete, 'topic.delete did not return self'
diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb
index eeb619ac2f..3b9e4f42a6 100644
--- a/activerecord/test/cases/reflection_test.rb
+++ b/activerecord/test/cases/reflection_test.rb
@@ -24,25 +24,25 @@ class ReflectionTest < ActiveRecord::TestCase
def test_read_attribute_names
assert_equal(
- %w( id title author_name author_email_address bonus_time written_on last_read content group approved replies_count parent_id parent_title type ).sort,
+ %w( id title author_name author_email_address bonus_time written_on last_read content group approved replies_count parent_id parent_title type created_at updated_at ).sort,
@first.attribute_names
)
end
def test_columns
- assert_equal 14, Topic.columns.length
+ assert_equal 16, Topic.columns.length
end
def test_columns_are_returned_in_the_order_they_were_declared
column_names = Topic.columns.map { |column| column.name }
- assert_equal %w(id title author_name author_email_address written_on bonus_time last_read content approved replies_count parent_id parent_title type group), column_names
+ assert_equal %w(id title author_name author_email_address written_on bonus_time last_read content approved replies_count parent_id parent_title type group created_at updated_at), column_names
end
def test_content_columns
content_columns = Topic.content_columns
content_column_names = content_columns.map {|column| column.name}
- assert_equal 10, content_columns.length
- assert_equal %w(title author_name author_email_address written_on bonus_time last_read content group approved parent_title).sort, content_column_names.sort
+ assert_equal 12, content_columns.length
+ assert_equal %w(title author_name author_email_address written_on bonus_time last_read content group approved parent_title created_at updated_at).sort, content_column_names.sort
end
def test_column_string_type_and_limit
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index f4f3dc4d5a..b44c716db8 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -1,4 +1,5 @@
require "cases/helper"
+require 'models/tag'
require 'models/tagging'
require 'models/post'
require 'models/topic'
@@ -17,7 +18,7 @@ require 'models/tyre'
class RelationTest < ActiveRecord::TestCase
fixtures :authors, :topics, :entrants, :developers, :companies, :developers_projects, :accounts, :categories, :categorizations, :posts, :comments,
- :taggings, :cars
+ :tags, :taggings, :cars
def test_bind_values
relation = Post.scoped
@@ -144,6 +145,16 @@ class RelationTest < ActiveRecord::TestCase
assert_equal entrants(:first).name, entrants.first.name
end
+ def test_finding_with_complex_order_and_limit
+ tags = Tag.includes(:taggings).order("REPLACE('abc', taggings.taggable_type, taggings.taggable_type)").limit(1).to_a
+ assert_equal 1, tags.length
+ end
+
+ def test_finding_with_complex_order
+ tags = Tag.includes(:taggings).order("REPLACE('abc', taggings.taggable_type, taggings.taggable_type)").to_a
+ assert_equal 2, tags.length
+ end
+
def test_finding_with_order_limit_and_offset
entrants = Entrant.order("id ASC").limit(2).offset(1)
@@ -372,7 +383,7 @@ class RelationTest < ActiveRecord::TestCase
lifo = authors.find_or_initialize_by_name('Lifo')
assert_equal "Lifo", lifo.name
- assert lifo.new_record?
+ assert !lifo.persisted?
assert_equal authors(:david), authors.find_or_initialize_by_name(:name => 'David')
end
@@ -382,7 +393,7 @@ class RelationTest < ActiveRecord::TestCase
lifo = authors.find_or_create_by_name('Lifo')
assert_equal "Lifo", lifo.name
- assert ! lifo.new_record?
+ assert lifo.persisted?
assert_equal authors(:david), authors.find_or_create_by_name(:name => 'David')
end
@@ -616,10 +627,10 @@ class RelationTest < ActiveRecord::TestCase
sparrow = birds.create
assert_kind_of Bird, sparrow
- assert sparrow.new_record?
+ assert !sparrow.persisted?
hen = birds.where(:name => 'hen').create
- assert ! hen.new_record?
+ assert hen.persisted?
assert_equal 'hen', hen.name
end
@@ -630,7 +641,7 @@ class RelationTest < ActiveRecord::TestCase
hen = birds.where(:name => 'hen').create!
assert_kind_of Bird, hen
- assert ! hen.new_record?
+ assert hen.persisted?
assert_equal 'hen', hen.name
end
diff --git a/activerecord/test/cases/session_store/sql_bypass.rb b/activerecord/test/cases/session_store/sql_bypass.rb
index f0ba166465..7402b2afd6 100644
--- a/activerecord/test/cases/session_store/sql_bypass.rb
+++ b/activerecord/test/cases/session_store/sql_bypass.rb
@@ -18,9 +18,9 @@ module ActiveRecord
assert !Session.table_exists?
end
- def test_new_record?
+ def test_persisted?
s = SqlBypass.new :data => 'foo', :session_id => 10
- assert s.new_record?, 'this is a new record!'
+ assert !s.persisted?, 'this is a new record!'
end
def test_not_loaded?
diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb
index 0fbcef4091..dd9de3510b 100644
--- a/activerecord/test/cases/transactions_test.rb
+++ b/activerecord/test/cases/transactions_test.rb
@@ -182,7 +182,7 @@ class TransactionTest < ActiveRecord::TestCase
:bonus_time => "2005-01-30t15:28:00.00+01:00",
:content => "Have a nice day",
:approved => false)
- new_record_snapshot = new_topic.new_record?
+ new_record_snapshot = !new_topic.persisted?
id_present = new_topic.has_attribute?(Topic.primary_key)
id_snapshot = new_topic.id
@@ -195,7 +195,7 @@ class TransactionTest < ActiveRecord::TestCase
flunk
rescue => e
assert_equal "Make the transaction rollback", e.message
- assert_equal new_record_snapshot, new_topic.new_record?, "The topic should have its old new_record value"
+ assert_equal new_record_snapshot, !new_topic.persisted?, "The topic should have its old persisted value"
assert_equal id_snapshot, new_topic.id, "The topic should have its old id"
assert_equal id_present, new_topic.has_attribute?(Topic.primary_key)
ensure
@@ -370,21 +370,21 @@ class TransactionTest < ActiveRecord::TestCase
assert topic_2.save
@first.save
@second.destroy
- assert_equal false, topic_1.new_record?
+ assert_equal true, topic_1.persisted?
assert_not_nil topic_1.id
- assert_equal false, topic_2.new_record?
+ assert_equal true, topic_2.persisted?
assert_not_nil topic_2.id
- assert_equal false, @first.new_record?
+ assert_equal true, @first.persisted?
assert_not_nil @first.id
assert_equal true, @second.destroyed?
raise ActiveRecord::Rollback
end
- assert_equal true, topic_1.new_record?
+ assert_equal false, topic_1.persisted?
assert_nil topic_1.id
- assert_equal true, topic_2.new_record?
+ assert_equal false, topic_2.persisted?
assert_nil topic_2.id
- assert_equal false, @first.new_record?
+ assert_equal true, @first.persisted?
assert_not_nil @first.id
assert_equal false, @second.destroyed?
end
diff --git a/activerecord/test/connections/native_oracle/connection.rb b/activerecord/test/connections/native_oracle/connection.rb
index c942036128..99f921879c 100644
--- a/activerecord/test/connections/native_oracle/connection.rb
+++ b/activerecord/test/connections/native_oracle/connection.rb
@@ -33,15 +33,3 @@ ActiveRecord::Base.configurations = {
ActiveRecord::Base.establish_connection 'arunit'
Course.establish_connection 'arunit2'
-# for assert_queries test helper
-ActiveRecord::Base.connection.class.class_eval do
- IGNORED_SELECT_SQL = [/^select .*nextval/i, /^SAVEPOINT/, /^ROLLBACK TO/, /^\s*select .* from ((all|user)_tab_columns|(all|user)_triggers|(all|user)_constraints)/im]
-
- def select_with_query_record(sql, name = nil)
- $queries_executed ||= []
- $queries_executed << sql unless IGNORED_SELECT_SQL.any? { |r| sql =~ r }
- select_without_query_record(sql, name)
- end
-
- alias_method_chain :select, :query_record
-end
diff --git a/activerecord/test/models/eye.rb b/activerecord/test/models/eye.rb
index 77f17b578e..dc8ae2b3f6 100644
--- a/activerecord/test/models/eye.rb
+++ b/activerecord/test/models/eye.rb
@@ -17,7 +17,7 @@ class Eye < ActiveRecord::Base
after_save :trace_after_save2
def trace_after_create
- (@after_create_callbacks_stack ||= []) << iris.new_record?
+ (@after_create_callbacks_stack ||= []) << !iris.persisted?
end
alias trace_after_create2 trace_after_create
diff --git a/activerecord/test/models/pirate.rb b/activerecord/test/models/pirate.rb
index d89c8cf381..f2c45053e7 100644
--- a/activerecord/test/models/pirate.rb
+++ b/activerecord/test/models/pirate.rb
@@ -48,7 +48,7 @@ class Pirate < ActiveRecord::Base
end
def reject_empty_ships_on_create(attributes)
- attributes.delete('_reject_me_if_new').present? && new_record?
+ attributes.delete('_reject_me_if_new').present? && !persisted?
end
attr_accessor :cancel_save_from_callback
diff --git a/activerecord/test/models/subject.rb b/activerecord/test/models/subject.rb
index d4b8b91de8..8e28f8b86b 100644
--- a/activerecord/test/models/subject.rb
+++ b/activerecord/test/models/subject.rb
@@ -8,7 +8,7 @@ class Subject < ActiveRecord::Base
protected
def set_email_address
- if self.new_record?
+ unless self.persisted?
self.author_email_address = 'test@test.com'
end
end
diff --git a/activerecord/test/models/topic.rb b/activerecord/test/models/topic.rb
index 82d4b5997f..6496f36f7e 100644
--- a/activerecord/test/models/topic.rb
+++ b/activerecord/test/models/topic.rb
@@ -89,7 +89,7 @@ class Topic < ActiveRecord::Base
end
def set_email_address
- if self.new_record?
+ unless self.persisted?
self.author_email_address = 'test@test.com'
end
end
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index bb80a1ca17..d4eb56c4d7 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -552,6 +552,7 @@ ActiveRecord::Schema.define do
t.string :parent_title
t.string :type
t.string :group
+ t.timestamps
end
create_table :toys, :primary_key => :toy_id ,:force => true do |t|