aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG2
-rw-r--r--activerecord/README.rdoc (renamed from activerecord/README)21
-rw-r--r--activerecord/Rakefile2
-rw-r--r--activerecord/activerecord.gemspec6
-rw-r--r--activerecord/install.rb30
-rw-r--r--activerecord/lib/active_record/association_preload.rb6
-rw-r--r--activerecord/lib/active_record/associations.rb31
-rw-r--r--activerecord/lib/active_record/associations/association_collection.rb24
-rw-r--r--activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb28
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_adapter.rb11
-rw-r--r--activerecord/lib/active_record/fixtures.rb2
-rw-r--r--activerecord/lib/active_record/log_subscriber.rb8
-rw-r--r--activerecord/lib/active_record/named_scope.rb4
-rw-r--r--activerecord/lib/active_record/persistence.rb2
-rw-r--r--activerecord/lib/active_record/railtie.rb6
-rw-r--r--activerecord/lib/active_record/railties/databases.rake2
-rw-r--r--activerecord/lib/active_record/relation.rb9
-rw-r--r--activerecord/lib/active_record/session_store.rb1
-rw-r--r--activerecord/lib/active_record/timestamp.rb19
-rw-r--r--activerecord/test/cases/adapters/mysql/active_schema_test.rb1
-rw-r--r--activerecord/test/cases/aggregations_test.rb2
-rw-r--r--activerecord/test/cases/ar_schema_test.rb2
-rw-r--r--activerecord/test/cases/associations/belongs_to_associations_test.rb2
-rw-r--r--activerecord/test/cases/associations/callbacks_test.rb2
-rw-r--r--activerecord/test/cases/associations/cascaded_eager_loading_test.rb1
-rw-r--r--activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb57
-rw-r--r--activerecord/test/cases/associations/inverse_associations_test.rb4
-rw-r--r--activerecord/test/cases/associations_test.rb32
-rw-r--r--activerecord/test/cases/base_test.rb12
-rw-r--r--activerecord/test/cases/finder_test.rb1
-rw-r--r--activerecord/test/cases/fixtures_test.rb6
-rw-r--r--activerecord/test/cases/log_subscriber_test.rb18
-rw-r--r--activerecord/test/cases/method_scoping_test.rb3
-rw-r--r--activerecord/test/cases/named_scope_test.rb10
-rw-r--r--activerecord/test/cases/nested_attributes_test.rb69
-rw-r--r--activerecord/test/cases/persistence_test.rb15
-rw-r--r--activerecord/test/cases/primary_keys_test.rb (renamed from activerecord/test/cases/pk_test.rb)4
-rw-r--r--activerecord/test/cases/query_cache_test.rb2
-rw-r--r--activerecord/test/cases/relation_scoping_test.rb23
-rw-r--r--activerecord/test/cases/relations_test.rb1
-rw-r--r--activerecord/test/cases/transaction_callbacks_test.rb1
-rw-r--r--activerecord/test/cases/validations/i18n_generate_message_validation_test.rb1
-rw-r--r--activerecord/test/cases/validations_test.rb5
-rw-r--r--activerecord/test/cases/xml_serialization_test.rb1
-rw-r--r--activerecord/test/fixtures/minivans.yml1
-rw-r--r--activerecord/test/models/country.rb7
-rw-r--r--activerecord/test/models/minivan.rb5
-rw-r--r--activerecord/test/models/person.rb2
-rw-r--r--activerecord/test/models/reference.rb5
-rw-r--r--activerecord/test/models/treaty.rb7
-rw-r--r--activerecord/test/schema/schema.rb16
51 files changed, 359 insertions, 173 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index a1a82fdff5..679fdafae8 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*Rails 3.0.0 [RC1] (unreleased)*
+* Changed update_attribute to not run callbacks and update the record directly in the database [Neeraj Singh]
+
* Add scoping and unscoped as the syntax to replace the old with_scope and with_exclusive_scope [José Valim]
* New rake task, db:migrate:status, displays status of migrations #4947 [Kevin Skoglund]
diff --git a/activerecord/README b/activerecord/README.rdoc
index d68eb28a64..0446180207 100644
--- a/activerecord/README
+++ b/activerecord/README.rdoc
@@ -309,28 +309,13 @@ Admit the Database:
== Download
-The latest version of Active Record can be found at
+The latest version of Active Record can be installed with Rubygems:
-* http://rubyforge.org/project/showfiles.php?group_id=182
+* gem install activerecord
Documentation can be found at
-* http://ar.rubyonrails.com
-
-
-== Installation
-
-The prefered method of installing Active Record is through its GEM file. You'll need to have
-RubyGems[http://rubygems.rubyforge.org/wiki/wiki.pl] installed for that, though. If you have,
-then use:
-
- % [sudo] gem install activerecord-1.10.0.gem
-
-You can also install Active Record the old-fashioned way with the following command:
-
- % [sudo] ruby install.rb
-
-from its distribution directory.
+* http://api.rubyonrails.org
== License
diff --git a/activerecord/Rakefile b/activerecord/Rakefile
index 392b717e0a..d9124c9776 100644
--- a/activerecord/Rakefile
+++ b/activerecord/Rakefile
@@ -172,7 +172,7 @@ Rake::RDocTask.new { |rdoc|
rdoc.options << '--line-numbers' << '--inline-source' << '-A cattr_accessor=object'
rdoc.options << '--charset' << 'utf-8'
rdoc.template = ENV['template'] ? "#{ENV['template']}.rb" : '../doc/template/horo'
- rdoc.rdoc_files.include('README', 'RUNNING_UNIT_TESTS', 'CHANGELOG')
+ rdoc.rdoc_files.include('README.rdoc', 'RUNNING_UNIT_TESTS', 'CHANGELOG')
rdoc.rdoc_files.include('lib/**/*.rb')
rdoc.rdoc_files.exclude('lib/active_record/vendor/*')
rdoc.rdoc_files.include('dev-utils/*.rb')
diff --git a/activerecord/activerecord.gemspec b/activerecord/activerecord.gemspec
index ce10404feb..67d521d56b 100644
--- a/activerecord/activerecord.gemspec
+++ b/activerecord/activerecord.gemspec
@@ -14,12 +14,12 @@ Gem::Specification.new do |s|
s.homepage = 'http://www.rubyonrails.org'
s.rubyforge_project = 'activerecord'
- s.files = Dir['CHANGELOG', 'README', 'examples/**/*', 'lib/**/*']
+ s.files = Dir['CHANGELOG', 'README.rdoc', 'examples/**/*', 'lib/**/*']
s.require_path = 'lib'
s.has_rdoc = true
- s.extra_rdoc_files = %w( README )
- s.rdoc_options.concat ['--main', 'README']
+ s.extra_rdoc_files = %w( README.rdoc )
+ s.rdoc_options.concat ['--main', 'README.rdoc']
s.add_dependency('activesupport', version)
s.add_dependency('activemodel', version)
diff --git a/activerecord/install.rb b/activerecord/install.rb
deleted file mode 100644
index c87398b1f4..0000000000
--- a/activerecord/install.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-require 'rbconfig'
-require 'find'
-require 'ftools'
-
-include Config
-
-# this was adapted from rdoc's install.rb by ways of Log4r
-
-$sitedir = CONFIG["sitelibdir"]
-unless $sitedir
- version = CONFIG["MAJOR"] + "." + CONFIG["MINOR"]
- $libdir = File.join(CONFIG["libdir"], "ruby", version)
- $sitedir = $:.find {|x| x =~ /site_ruby/ }
- if !$sitedir
- $sitedir = File.join($libdir, "site_ruby")
- elsif $sitedir !~ Regexp.quote(version)
- $sitedir = File.join($sitedir, version)
- end
-end
-
-# the actual gruntwork
-Dir.chdir("lib")
-
-Find.find("active_record", "active_record.rb") { |f|
- if f[-3..-1] == ".rb"
- File::install(f, File.join($sitedir, *f.split(/\//)), 0644, true)
- else
- File::makedirs(File.join($sitedir, *f.split(/\//)))
- end
-}
diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb
index cbec5789fd..08601f8ef9 100644
--- a/activerecord/lib/active_record/association_preload.rb
+++ b/activerecord/lib/active_record/association_preload.rb
@@ -112,13 +112,13 @@ module ActiveRecord
# Not all records have the same class, so group then preload
# group on the reflection itself so that if various subclass share the same association then we do not split them
# unnecessarily
- records.group_by {|record| class_to_reflection[record.class] ||= record.class.reflections[association]}.each do |reflection, records|
+ records.group_by { |record| class_to_reflection[record.class] ||= record.class.reflections[association]}.each do |reflection, _records|
raise ConfigurationError, "Association named '#{ association }' was not found; perhaps you misspelled it?" unless reflection
# 'reflection.macro' can return 'belongs_to', 'has_many', etc. Thus,
# the following could call 'preload_belongs_to_association',
# 'preload_has_many_association', etc.
- send("preload_#{reflection.macro}_association", records, reflection, preload_options)
+ send("preload_#{reflection.macro}_association", _records, reflection, preload_options)
end
end
@@ -378,7 +378,7 @@ module ActiveRecord
:order => preload_options[:order] || options[:order]
}
- reflection.klass.unscoped.apply_finder_options(find_options).to_a
+ reflection.klass.scoped.apply_finder_options(find_options).to_a
end
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index d67df64f59..1b9b725dd4 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -3,6 +3,7 @@ require 'active_support/core_ext/enumerable'
require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/string/conversions'
+require 'active_support/core_ext/module/remove_method'
module ActiveRecord
class InverseOfAssociationNotFoundError < ActiveRecordError #:nodoc:
@@ -1354,7 +1355,7 @@ module ActiveRecord
end
def association_accessor_methods(reflection, association_proxy_class)
- define_method(reflection.name) do |*params|
+ redefine_method(reflection.name) do |*params|
force_reload = params.first unless params.empty?
association = association_instance_get(reflection.name)
@@ -1371,12 +1372,12 @@ module ActiveRecord
association.target.nil? ? nil : association
end
- define_method("loaded_#{reflection.name}?") do
+ redefine_method("loaded_#{reflection.name}?") do
association = association_instance_get(reflection.name)
association && association.loaded?
end
-
- define_method("#{reflection.name}=") do |new_value|
+
+ redefine_method("#{reflection.name}=") do |new_value|
association = association_instance_get(reflection.name)
if association.nil? || association.target != new_value
@@ -1386,8 +1387,8 @@ module ActiveRecord
association.replace(new_value)
association_instance_set(reflection.name, new_value.nil? ? nil : association)
end
-
- define_method("set_#{reflection.name}_target") do |target|
+
+ redefine_method("set_#{reflection.name}_target") do |target|
return if target.nil? and association_proxy_class == BelongsToAssociation
association = association_proxy_class.new(self, reflection)
association.target = target
@@ -1396,7 +1397,7 @@ module ActiveRecord
end
def collection_reader_method(reflection, association_proxy_class)
- define_method(reflection.name) do |*params|
+ redefine_method(reflection.name) do |*params|
force_reload = params.first unless params.empty?
association = association_instance_get(reflection.name)
@@ -1409,8 +1410,8 @@ module ActiveRecord
association
end
-
- define_method("#{reflection.name.to_s.singularize}_ids") do
+
+ redefine_method("#{reflection.name.to_s.singularize}_ids") do
if send(reflection.name).loaded? || reflection.options[:finder_sql]
send(reflection.name).map(&:id)
else
@@ -1430,14 +1431,14 @@ module ActiveRecord
collection_reader_method(reflection, association_proxy_class)
if writer
- define_method("#{reflection.name}=") do |new_value|
+ redefine_method("#{reflection.name}=") do |new_value|
# Loads proxy class instance (defined in collection_reader_method) if not already loaded
association = send(reflection.name)
association.replace(new_value)
association
end
-
- define_method("#{reflection.name.to_s.singularize}_ids=") do |new_value|
+
+ redefine_method("#{reflection.name.to_s.singularize}_ids=") do |new_value|
ids = (new_value || []).reject { |nid| nid.blank? }.map(&:to_i)
send("#{reflection.name}=", reflection.klass.find(ids).index_by(&:id).values_at(*ids))
end
@@ -1445,7 +1446,7 @@ module ActiveRecord
end
def association_constructor_method(constructor, reflection, association_proxy_class)
- define_method("#{constructor}_#{reflection.name}") do |*params|
+ redefine_method("#{constructor}_#{reflection.name}") do |*params|
attributees = params.first unless params.empty?
replace_existing = params[1].nil? ? true : params[1]
association = association_instance_get(reflection.name)
@@ -1486,8 +1487,8 @@ module ActiveRecord
end
def add_touch_callbacks(reflection, touch_attribute)
- method_name = "belongs_to_touch_after_save_or_destroy_for_#{reflection.name}".to_sym
- define_method(method_name) do
+ method_name = :"belongs_to_touch_after_save_or_destroy_for_#{reflection.name}"
+ redefine_method(method_name) do
association = send(reflection.name)
if touch_attribute == true
diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb
index f4e34657a5..f346a19a3a 100644
--- a/activerecord/lib/active_record/associations/association_collection.rb
+++ b/activerecord/lib/active_record/associations/association_collection.rb
@@ -218,9 +218,9 @@ module ActiveRecord
# are actually removed from the database, that depends precisely on
# +delete_records+. They are in any case removed from the collection.
def delete(*records)
- remove_records(records) do |records, old_records|
+ remove_records(records) do |_records, old_records|
delete_records(old_records) if old_records.any?
- records.each { |record| @target.delete(record) }
+ _records.each { |record| @target.delete(record) }
end
end
@@ -231,7 +231,7 @@ module ActiveRecord
# ignoring the +:dependent+ option.
def destroy(*records)
records = find(records) if records.any? {|record| record.kind_of?(Fixnum) || record.kind_of?(String)}
- remove_records(records) do |records, old_records|
+ remove_records(records) do |_records, old_records|
old_records.each { |record| record.destroy }
end
@@ -396,11 +396,12 @@ module ActiveRecord
if @target.is_a?(Array) && @target.any?
@target = find_target.map do |f|
i = @target.index(f)
- t = @target.delete_at(i) if i
- if t && t.changed?
- t
+ if i
+ @target.delete_at(i).tap do |t|
+ keys = ["id"] + t.changes.keys + (f.attribute_names - t.attribute_names)
+ t.attributes = f.attributes.except(*keys)
+ end
else
- f.mark_for_destruction if t && t.marked_for_destruction?
f
end
end + @target
@@ -477,7 +478,14 @@ module ActiveRecord
callback(:before_add, record)
yield(record) if block_given?
@target ||= [] unless loaded?
- @target << record unless @reflection.options[:uniq] && @target.include?(record)
+ index = @target.index(record)
+ unless @reflection.options[:uniq] && index
+ if index
+ @target[index] = record
+ else
+ @target << record
+ end
+ end
callback(:after_add, record)
set_inverse_instance(record, @owner)
record
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 c989c3536d..e61af93d1e 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
@@ -45,17 +45,23 @@ module ActiveRecord
if @reflection.options[:insert_sql]
@owner.connection.insert(interpolate_sql(@reflection.options[:insert_sql], record))
else
- relation = Arel::Table.new(@reflection.options[:join_table])
+ relation = Arel::Table.new(@reflection.options[:join_table])
+ timestamps = record_timestamp_columns(record)
+ timezone = record.send(:current_time_from_proper_timezone) if timestamps.any?
+
attributes = columns.inject({}) do |attrs, column|
- case column.name.to_s
+ name = column.name
+ case name.to_s
when @reflection.primary_key_name.to_s
- attrs[relation[column.name]] = owner_quoted_id
+ attrs[relation[name]] = @owner.id
when @reflection.association_foreign_key.to_s
- attrs[relation[column.name]] = record.quoted_id
+ attrs[relation[name]] = record.id
+ when *timestamps
+ attrs[relation[name]] = timezone
else
- if record.has_attribute?(column.name)
- value = @owner.send(:quote_value, record[column.name], column)
- attrs[relation[column.name]] = value unless value.nil?
+ if record.has_attribute?(name)
+ value = @owner.send(:quote_value, record[name], column)
+ attrs[relation[name]] = value unless value.nil?
end
end
attrs
@@ -117,6 +123,14 @@ module ActiveRecord
build_record(attributes, &block)
end
end
+
+ def record_timestamp_columns(record)
+ if record.record_timestamps
+ record.send(:all_timestamp_attributes).map(&:to_s)
+ else
+ []
+ end
+ end
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index be8d1bd76b..6072481411 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -199,11 +199,14 @@ module ActiveRecord
def log(sql, name)
name ||= "SQL"
- result = nil
- ActiveSupport::Notifications.instrument("sql.active_record",
- :sql => sql, :name => name, :connection_id => self.object_id) do
- @runtime += Benchmark.ms { result = yield }
+ instrumenter = ActiveSupport::Notifications.instrumenter
+
+ result = instrumenter.instrument("sql.active_record",
+ :sql => sql, :name => name, :connection_id => object_id) do
+ yield
end
+ @runtime += instrumenter.elapsed
+
result
rescue Exception => e
message = "#{e.class.name}: #{e.message}: #{sql}"
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index 5bf43b3a72..657303fd14 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -871,7 +871,7 @@ module ActiveRecord
table_names.each do |table_name|
table_name = table_name.to_s.tr('./', '_')
- define_method(table_name) do |*fixtures|
+ redefine_method(table_name) do |*fixtures|
force_reload = fixtures.pop if fixtures.last == true || fixtures.last == :reload
@fixture_cache[table_name] ||= {}
diff --git a/activerecord/lib/active_record/log_subscriber.rb b/activerecord/lib/active_record/log_subscriber.rb
index 71065f9908..278e192e59 100644
--- a/activerecord/lib/active_record/log_subscriber.rb
+++ b/activerecord/lib/active_record/log_subscriber.rb
@@ -6,14 +6,16 @@ module ActiveRecord
end
def sql(event)
+ return unless logger.debug?
+
name = '%s (%.1fms)' % [event.payload[:name], event.duration]
sql = event.payload[:sql].squeeze(' ')
if odd?
- name = color(name, :cyan, true)
+ name = color(name, CYAN, true)
sql = color(sql, nil, true)
else
- name = color(name, :magenta, true)
+ name = color(name, MAGENTA, true)
end
debug " #{name} #{sql}"
@@ -29,4 +31,4 @@ module ActiveRecord
end
end
-ActiveRecord::LogSubscriber.attach_to :active_record \ No newline at end of file
+ActiveRecord::LogSubscriber.attach_to :active_record
diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb
index 849ec9c884..417ff4b5eb 100644
--- a/activerecord/lib/active_record/named_scope.rb
+++ b/activerecord/lib/active_record/named_scope.rb
@@ -26,7 +26,7 @@ module ActiveRecord
# You can define a \scope that applies to all finders using
# ActiveRecord::Base.default_scope.
def scoped(options = nil)
- if options.present?
+ if options
scoped.apply_finder_options(options)
else
current_scoped_methods ? relation.merge(current_scoped_methods) : relation.clone
@@ -105,7 +105,7 @@ module ActiveRecord
extension ? relation.extending(extension) : relation
end
- singleton_class.send :define_method, name, &scopes[name]
+ singleton_class.send(:redefine_method, name, &scopes[name])
end
def named_scope(*args, &block)
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index 68f5be63d6..b587abd5d0 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -112,6 +112,8 @@ module ActiveRecord
# * does not work on attr_accessor attributes. The attribute that is being updated must be column name.
#
def update_attribute(name, value)
+ raise ActiveRecordError, "#{name.to_s} is marked as readonly" if self.class.readonly_attributes.include? name.to_s
+
changes = record_update_timestamps || {}
if name
diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb
index eff51a7c87..78fdb77216 100644
--- a/activerecord/lib/active_record/railtie.rb
+++ b/activerecord/lib/active_record/railtie.rb
@@ -22,6 +22,12 @@ module ActiveRecord
load "active_record/railties/databases.rake"
end
+ # When loading console, force ActiveRecord to be loaded to avoid cross
+ # references when loading a constant for the first time.
+ console do
+ ActiveRecord::Base
+ end
+
initializer "active_record.initialize_timezone" do
ActiveSupport.on_load(:active_record) do
self.time_zone_aware_attributes = true
diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake
index 5024787c3c..2c17c74ab4 100644
--- a/activerecord/lib/active_record/railties/databases.rake
+++ b/activerecord/lib/active_record/railties/databases.rake
@@ -274,7 +274,7 @@ namespace :db do
task :setup => [ 'db:create', 'db:schema:load', 'db:seed' ]
desc 'Load the seed data from db/seeds.rb'
- task :seed => :environment do
+ task :seed => 'db:abort_if_pending_migrations' do
seed_file = File.join(Rails.root, 'db', 'seeds.rb')
load(seed_file) if File.exist?(seed_file)
end
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index 7499100f55..86a210d2be 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -13,14 +13,15 @@ module ActiveRecord
delegate :to_xml, :to_yaml, :length, :collect, :map, :each, :all?, :include?, :to => :to_a
delegate :insert, :to => :arel
- attr_reader :table, :klass
+ attr_reader :table, :klass, :loaded
attr_accessor :extensions
+ alias :loaded? :loaded
def initialize(klass, table)
@klass, @table = klass, table
@implicit_readonly = nil
- @loaded = nil
+ @loaded = false
SINGLE_VALUE_METHODS.each {|v| instance_variable_set(:"@#{v}_value", nil)}
(ASSOCIATION_METHODS + MULTI_VALUE_METHODS).each {|v| instance_variable_set(:"@#{v}_values", [])}
@@ -292,10 +293,6 @@ module ActiveRecord
where(@klass.primary_key => id_or_array).delete_all
end
- def loaded?
- @loaded
- end
-
def reload
reset
to_a # force reload
diff --git a/activerecord/lib/active_record/session_store.rb b/activerecord/lib/active_record/session_store.rb
index df2f429c5d..7ea7fb5c51 100644
--- a/activerecord/lib/active_record/session_store.rb
+++ b/activerecord/lib/active_record/session_store.rb
@@ -294,7 +294,6 @@ module ActiveRecord
private
def get_session(env, sid)
Base.silence do
- sid ||= generate_sid
session = find_session(sid)
env[SESSION_RECORD_KEY] = session
[sid, session.data]
diff --git a/activerecord/lib/active_record/timestamp.rb b/activerecord/lib/active_record/timestamp.rb
index 341cc87be5..6c1e376745 100644
--- a/activerecord/lib/active_record/timestamp.rb
+++ b/activerecord/lib/active_record/timestamp.rb
@@ -39,8 +39,9 @@ module ActiveRecord
if record_timestamps
current_time = current_time_from_proper_timezone
- write_attribute('created_at', current_time) if respond_to?(:created_at) && created_at.nil?
- write_attribute('created_on', current_time) if respond_to?(:created_on) && created_on.nil?
+ timestamp_attributes_for_create.each do |column|
+ write_attribute(column.to_s, current_time) if respond_to?(column) && self.send(column).nil?
+ end
timestamp_attributes_for_update_in_model.each do |column|
write_attribute(column.to_s, current_time) if self.send(column).nil?
@@ -65,7 +66,19 @@ module ActiveRecord
end
def timestamp_attributes_for_update_in_model #:nodoc:
- [:updated_at, :updated_on].select { |elem| respond_to?(elem) }
+ timestamp_attributes_for_update.select { |elem| respond_to?(elem) }
+ end
+
+ def timestamp_attributes_for_update #:nodoc:
+ [:updated_at, :updated_on]
+ end
+
+ def timestamp_attributes_for_create #:nodoc:
+ [:created_at, :created_on]
+ end
+
+ def all_timestamp_attributes #:nodoc:
+ timestamp_attributes_for_update + timestamp_attributes_for_create
end
def current_time_from_proper_timezone #:nodoc:
diff --git a/activerecord/test/cases/adapters/mysql/active_schema_test.rb b/activerecord/test/cases/adapters/mysql/active_schema_test.rb
index 6e6645511c..ed4efdc1c0 100644
--- a/activerecord/test/cases/adapters/mysql/active_schema_test.rb
+++ b/activerecord/test/cases/adapters/mysql/active_schema_test.rb
@@ -101,6 +101,7 @@ class ActiveSchemaTest < ActiveRecord::TestCase
#we need to actually modify some data, so we make execute point to the original method
ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
alias_method :execute_with_stub, :execute
+ remove_method :execute
alias_method :execute, :execute_without_stub
end
yield
diff --git a/activerecord/test/cases/aggregations_test.rb b/activerecord/test/cases/aggregations_test.rb
index 74588b4f47..9e285e57dc 100644
--- a/activerecord/test/cases/aggregations_test.rb
+++ b/activerecord/test/cases/aggregations_test.rb
@@ -125,7 +125,7 @@ class OverridingAggregationsTest < ActiveRecord::TestCase
class Name; end
class DifferentName; end
- class Person < ActiveRecord::Base
+ class Person < ActiveRecord::Base
composed_of :composed_of, :mapping => %w(person_first_name first_name)
end
diff --git a/activerecord/test/cases/ar_schema_test.rb b/activerecord/test/cases/ar_schema_test.rb
index 665c387d5d..588adc38e3 100644
--- a/activerecord/test/cases/ar_schema_test.rb
+++ b/activerecord/test/cases/ar_schema_test.rb
@@ -28,7 +28,7 @@ if ActiveRecord::Base.connection.supports_migrations?
assert_equal 7, ActiveRecord::Migrator::current_version
end
- def test_schema_raises_an_error_for_invalid_column_ntype
+ def test_schema_raises_an_error_for_invalid_column_type
assert_raise NoMethodError do
ActiveRecord::Schema.define(:version => 8) do
create_table :vegetables do |t|
diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb
index fb1e6e7e70..4d5769d173 100644
--- a/activerecord/test/cases/associations/belongs_to_associations_test.rb
+++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb
@@ -5,8 +5,6 @@ require 'models/company'
require 'models/topic'
require 'models/reply'
require 'models/computer'
-require 'models/customer'
-require 'models/order'
require 'models/post'
require 'models/author'
require 'models/tag'
diff --git a/activerecord/test/cases/associations/callbacks_test.rb b/activerecord/test/cases/associations/callbacks_test.rb
index 91b1af125e..15537d6940 100644
--- a/activerecord/test/cases/associations/callbacks_test.rb
+++ b/activerecord/test/cases/associations/callbacks_test.rb
@@ -1,8 +1,6 @@
require "cases/helper"
require 'models/post'
-require 'models/comment'
require 'models/author'
-require 'models/category'
require 'models/project'
require 'models/developer'
diff --git a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb
index f5d59c9a43..b93e49613d 100644
--- a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb
+++ b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb
@@ -2,7 +2,6 @@ require "cases/helper"
require 'models/post'
require 'models/comment'
require 'models/author'
-require 'models/category'
require 'models/categorization'
require 'models/company'
require 'models/topic'
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 b11969a841..6b4a1d9408 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
@@ -2,20 +2,14 @@ require "cases/helper"
require 'models/developer'
require 'models/project'
require 'models/company'
-require 'models/topic'
-require 'models/reply'
-require 'models/computer'
require 'models/customer'
require 'models/order'
require 'models/categorization'
require 'models/category'
require 'models/post'
require 'models/author'
-require 'models/comment'
require 'models/tag'
require 'models/tagging'
-require 'models/person'
-require 'models/reader'
require 'models/parrot'
require 'models/pirate'
require 'models/treasure'
@@ -24,6 +18,8 @@ require 'models/club'
require 'models/member'
require 'models/membership'
require 'models/sponsor'
+require 'models/country'
+require 'models/treaty'
require 'active_support/core_ext/string/conversions'
class ProjectWithAfterCreateHook < ActiveRecord::Base
@@ -83,6 +79,55 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects,
:parrots, :pirates, :treasures, :price_estimates, :tags, :taggings
+ def setup_data_for_habtm_case
+ ActiveRecord::Base.connection.execute('delete from countries_treaties')
+
+ country = Country.new(:name => 'India')
+ country.country_id = 'c1'
+ country.save!
+
+ treaty = Treaty.new(:name => 'peace')
+ treaty.treaty_id = 't1'
+ country.treaties << treaty
+ end
+
+ def test_should_property_quote_string_primary_keys
+ setup_data_for_habtm_case
+
+ con = ActiveRecord::Base.connection
+ sql = 'select * from countries_treaties'
+ record = con.select_rows(sql).last
+ assert_equal 'c1', record[0]
+ assert_equal 't1', record[1]
+ end
+
+ def test_should_record_timestamp_for_join_table
+ setup_data_for_habtm_case
+
+ con = ActiveRecord::Base.connection
+ sql = 'select * from countries_treaties'
+ record = con.select_rows(sql).last
+ assert_not_nil record[2]
+ assert_not_nil record[3]
+ assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[2]
+ assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[3]
+ end
+
+ def test_should_record_timestamp_for_join_table_only_if_timestamp_should_be_recorded
+ begin
+ Treaty.record_timestamps = false
+ setup_data_for_habtm_case
+
+ con = ActiveRecord::Base.connection
+ sql = 'select * from countries_treaties'
+ record = con.select_rows(sql).last
+ assert_nil record[2]
+ assert_nil record[3]
+ ensure
+ Treaty.record_timestamps = true
+ end
+ end
+
def test_has_and_belongs_to_many
david = Developer.find(1)
diff --git a/activerecord/test/cases/associations/inverse_associations_test.rb b/activerecord/test/cases/associations/inverse_associations_test.rb
index 34d24a2948..fa5c2e49df 100644
--- a/activerecord/test/cases/associations/inverse_associations_test.rb
+++ b/activerecord/test/cases/associations/inverse_associations_test.rb
@@ -412,7 +412,7 @@ class InverseBelongsToTests < ActiveRecord::TestCase
i = interests(:trainspotting)
m = i.man
assert_not_nil m.interests
- iz = m.interests.detect {|iz| iz.id == i.id}
+ iz = m.interests.detect { |_iz| _iz.id == i.id}
assert_not_nil iz
assert_equal i.topic, iz.topic, "Interest topics should be the same before changes to child"
i.topic = 'Eating cheese with a spoon'
@@ -516,7 +516,7 @@ class InversePolymorphicBelongsToTests < ActiveRecord::TestCase
i = interests(:llama_wrangling)
m = i.polymorphic_man
assert_not_nil m.polymorphic_interests
- iz = m.polymorphic_interests.detect {|iz| iz.id == i.id}
+ iz = m.polymorphic_interests.detect { |_iz| _iz.id == i.id}
assert_not_nil iz
assert_equal i.topic, iz.topic, "Interest topics should be the same before changes to child"
i.topic = 'Eating cheese with a spoon'
diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb
index 4ae776c35a..a1c794c084 100644
--- a/activerecord/test/cases/associations_test.rb
+++ b/activerecord/test/cases/associations_test.rb
@@ -2,11 +2,6 @@ require "cases/helper"
require 'models/developer'
require 'models/project'
require 'models/company'
-require 'models/topic'
-require 'models/reply'
-require 'models/computer'
-require 'models/customer'
-require 'models/order'
require 'models/categorization'
require 'models/category'
require 'models/post'
@@ -17,18 +12,31 @@ require 'models/tagging'
require 'models/person'
require 'models/reader'
require 'models/parrot'
-require 'models/pirate'
-require 'models/treasure'
-require 'models/price_estimate'
-require 'models/club'
-require 'models/member'
-require 'models/membership'
-require 'models/sponsor'
+require 'models/ship_part'
+require 'models/ship'
class AssociationsTest < ActiveRecord::TestCase
fixtures :accounts, :companies, :developers, :projects, :developers_projects,
:computers, :people, :readers
+ def test_loading_the_association_target_should_keep_child_records_marked_for_destruction
+ ship = Ship.create!(:name => "The good ship Dollypop")
+ part = ship.parts.create!(:name => "Mast")
+ part.mark_for_destruction
+ ship.parts.send(:load_target)
+ assert ship.parts[0].marked_for_destruction?
+ end
+
+ def test_loading_the_association_target_should_load_most_recent_attributes_for_child_records_marked_for_destruction
+ ship = Ship.create!(:name => "The good ship Dollypop")
+ part = ship.parts.create!(:name => "Mast")
+ part.mark_for_destruction
+ ShipPart.find(part.id).update_attribute(:name, 'Deck')
+ ship.parts.send(:load_target)
+ assert_equal 'Deck', ship.parts[0].name
+ end
+
+
def test_include_with_order_works
assert_nothing_raised {Account.find(:first, :order => 'id', :include => :firm)}
assert_nothing_raised {Account.find(:first, :order => :id, :include => :firm)}
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 831dd446ad..df6895f0d0 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -123,6 +123,14 @@ class BasicsTest < ActiveRecord::TestCase
assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"]
else
assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"].to_s(:db)
+
+ developer.created_at = "345643456"
+ assert_equal developer.created_at_before_type_cast, "345643456"
+ assert_equal developer.created_at, nil
+
+ developer.created_at = "2010-03-21T21:23:32+01:00"
+ assert_equal developer.created_at_before_type_cast, "2010-03-21T21:23:32+01:00"
+ assert_equal developer.created_at, Time.parse("2010-03-21T21:23:32+01:00")
end
end
@@ -1816,8 +1824,8 @@ class BasicsTest < ActiveRecord::TestCase
def test_to_xml_with_block
value = "Rockin' the block"
- xml = Company.new.to_xml(:skip_instruct => true) do |xml|
- xml.tag! "arbitrary-element", value
+ xml = Company.new.to_xml(:skip_instruct => true) do |_xml|
+ _xml.tag! "arbitrary-element", value
end
assert_equal "<company>", xml.first(9)
assert xml.include?(%(<arbitrary-element>#{value}</arbitrary-element>))
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index 860d330a7f..a107c1a474 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -10,7 +10,6 @@ require 'models/entrant'
require 'models/project'
require 'models/developer'
require 'models/customer'
-require 'models/job'
class DynamicFinderMatchTest < ActiveRecord::TestCase
def test_find_no_match
diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb
index 8008b86f81..93f8749255 100644
--- a/activerecord/test/cases/fixtures_test.rb
+++ b/activerecord/test/cases/fixtures_test.rb
@@ -36,7 +36,7 @@ class FixturesTest < ActiveRecord::TestCase
fixtures = nil
assert_nothing_raised { fixtures = create_fixtures(name) }
assert_kind_of(Fixtures, fixtures)
- fixtures.each { |name, fixture|
+ fixtures.each { |_name, fixture|
fixture.each { |key, value|
assert_match(MATCH_ATTRIBUTE_NAME, key)
}
@@ -229,9 +229,9 @@ if Account.connection.respond_to?(:reset_pk_sequence!)
def test_create_fixtures_resets_sequences_when_not_cached
@instances.each do |instance|
- max_id = create_fixtures(instance.class.table_name).inject(0) do |max_id, (name, fixture)|
+ max_id = create_fixtures(instance.class.table_name).inject(0) do |_max_id, (name, fixture)|
fixture_id = fixture['id'].to_i
- fixture_id > max_id ? fixture_id : max_id
+ fixture_id > _max_id ? fixture_id : _max_id
end
# Clone the last fixture to check that it gets the next greatest id.
diff --git a/activerecord/test/cases/log_subscriber_test.rb b/activerecord/test/cases/log_subscriber_test.rb
index cde383783b..342daa19df 100644
--- a/activerecord/test/cases/log_subscriber_test.rb
+++ b/activerecord/test/cases/log_subscriber_test.rb
@@ -4,6 +4,7 @@ require "active_support/log_subscriber/test_helper"
class LogSubscriberTest < ActiveRecord::TestCase
include ActiveSupport::LogSubscriber::TestHelper
+ include ActiveSupport::BufferedLogger::Severity
def setup
@old_logger = ActiveRecord::Base.logger
@@ -39,4 +40,21 @@ class LogSubscriberTest < ActiveRecord::TestCase
assert_match(/CACHE/, @logger.logged(:debug).last)
assert_match(/SELECT .*?FROM .?developers.?/i, @logger.logged(:debug).last)
end
+
+ def test_basic_query_doesnt_log_when_level_is_not_debug
+ @logger.level = INFO
+ Developer.all
+ wait
+ assert_equal 0, @logger.logged(:debug).size
+ end
+
+ def test_cached_queries_doesnt_log_when_level_is_not_debug
+ @logger.level = INFO
+ ActiveRecord::Base.cache do
+ Developer.all
+ Developer.all
+ end
+ wait
+ assert_equal 0, @logger.logged(:debug).size
+ end
end
diff --git a/activerecord/test/cases/method_scoping_test.rb b/activerecord/test/cases/method_scoping_test.rb
index 4e8ce1dac1..774b50e2e4 100644
--- a/activerecord/test/cases/method_scoping_test.rb
+++ b/activerecord/test/cases/method_scoping_test.rb
@@ -8,7 +8,6 @@ require 'models/author'
require 'models/developer'
require 'models/project'
require 'models/comment'
-require 'models/category'
class MethodScopingTest < ActiveRecord::TestCase
fixtures :authors, :developers, :projects, :comments, :posts, :developers_projects
@@ -543,4 +542,4 @@ class NestedScopingTest < ActiveRecord::TestCase
assert_equal 1, scoped_authors.size
assert_equal authors(:david).attributes, scoped_authors.first.attributes
end
-end \ No newline at end of file
+end
diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb
index dc85b395d3..7c037b20c5 100644
--- a/activerecord/test/cases/named_scope_test.rb
+++ b/activerecord/test/cases/named_scope_test.rb
@@ -270,27 +270,27 @@ class NamedScopeTest < ActiveRecord::TestCase
assert Topic.base.many?
end
- def test_should_build_with_proxy_options
+ def test_should_build_on_top_of_named_scope
topic = Topic.approved.build({})
assert topic.approved
end
- def test_should_build_new_with_proxy_options
+ def test_should_build_new_on_top_of_named_scope
topic = Topic.approved.new
assert topic.approved
end
- def test_should_create_with_proxy_options
+ def test_should_create_on_top_of_named_scope
topic = Topic.approved.create({})
assert topic.approved
end
- def test_should_create_with_bang_with_proxy_options
+ def test_should_create_with_bang_on_top_of_named_scope
topic = Topic.approved.create!({})
assert topic.approved
end
- def test_should_build_with_proxy_options_chained
+ def test_should_build_on_top_of_chained_named_scopes
topic = Topic.approved.by_lifo.build({})
assert topic.approved
assert_equal 'lifo', topic.author_name
diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb
index c9ea0d8c40..df09bbd46a 100644
--- a/activerecord/test/cases/nested_attributes_test.rb
+++ b/activerecord/test/cases/nested_attributes_test.rb
@@ -59,6 +59,7 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase
pirate.save!
assert_equal 1, pirate.birds_with_reject_all_blank.count
+ assert_equal 'Tweetie', pirate.birds_with_reject_all_blank.first.name
end
def test_should_raise_an_ArgumentError_for_non_existing_associations
@@ -74,7 +75,7 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase
ship = pirate.create_ship(:name => 'Nights Dirty Lightning')
assert_no_difference('Ship.count') do
- pirate.update_attributes(:ship_attributes => { '_destroy' => true })
+ pirate.update_attributes(:ship_attributes => { '_destroy' => true, :id => ship.id })
end
end
@@ -100,7 +101,8 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase
pirate.ship_attributes = { :name => 'Red Pearl', :_reject_me_if_new => true }
assert_no_difference('Ship.count') { pirate.save! }
- # pirate.reject_empty_ships_on_create returns false for saved records
+ # pirate.reject_empty_ships_on_create returns false for saved pirate records
+ # in the previous step note that pirate gets saved but ship fails
pirate.ship_attributes = { :name => 'Red Pearl', :_reject_me_if_new => true }
assert_difference('Ship.count') { pirate.save! }
end
@@ -266,6 +268,28 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
end
assert_equal 'Mayflower', @ship.reload.name
end
+
+ def test_should_update_existing_when_update_only_is_true_and_id_is_given
+ @ship.delete
+ @ship = @pirate.create_update_only_ship(:name => 'Nights Dirty Lightning')
+
+ assert_no_difference('Ship.count') do
+ @pirate.update_attributes(:update_only_ship_attributes => { :name => 'Mayflower', :id => @ship.id })
+ end
+ assert_equal 'Mayflower', @ship.reload.name
+ end
+
+ def test_should_destroy_existing_when_update_only_is_true_and_id_is_given_and_is_marked_for_destruction
+ Pirate.accepts_nested_attributes_for :update_only_ship, :update_only => true, :allow_destroy => true
+ @ship.delete
+ @ship = @pirate.create_update_only_ship(:name => 'Nights Dirty Lightning')
+
+ assert_difference('Ship.count', -1) do
+ @pirate.update_attributes(:update_only_ship_attributes => { :name => 'Mayflower', :id => @ship.id, :_destroy => true })
+ end
+ Pirate.accepts_nested_attributes_for :update_only_ship, :update_only => true, :allow_destroy => false
+ end
+
end
class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase
@@ -411,6 +435,27 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase
end
assert_equal 'Arr', @pirate.reload.catchphrase
end
+
+ def test_should_update_existing_when_update_only_is_true_and_id_is_given
+ @pirate.delete
+ @pirate = @ship.create_update_only_pirate(:catchphrase => 'Aye')
+
+ assert_no_difference('Pirate.count') do
+ @ship.update_attributes(:update_only_pirate_attributes => { :catchphrase => 'Arr', :id => @pirate.id })
+ end
+ assert_equal 'Arr', @pirate.reload.catchphrase
+ end
+
+ def test_should_destroy_existing_when_update_only_is_true_and_id_is_given_and_is_marked_for_destruction
+ Ship.accepts_nested_attributes_for :update_only_pirate, :update_only => true, :allow_destroy => true
+ @pirate.delete
+ @pirate = @ship.create_update_only_pirate(:catchphrase => 'Aye')
+
+ assert_difference('Pirate.count', -1) do
+ @ship.update_attributes(:update_only_pirate_attributes => { :catchphrase => 'Arr', :id => @pirate.id, :_destroy => true })
+ end
+ Ship.accepts_nested_attributes_for :update_only_pirate, :update_only => true, :allow_destroy => false
+ end
end
module NestedAttributesOnACollectionAssociationTests
@@ -811,7 +856,25 @@ class TestHasManyAutosaveAssociationWhichItselfHasAutosaveAssociations < ActiveR
@part = @ship.parts.create!(:name => "Mast")
@trinket = @part.trinkets.create!(:name => "Necklace")
end
-
+
+ test "if association is not loaded and association record is saved and then in memory record attributes should be saved" do
+ @ship.parts_attributes=[{:id => @part.id,:name =>'Deck'}]
+ assert_equal 1, @ship.parts.proxy_target.size
+ assert_equal 'Deck', @ship.parts[0].name
+ end
+
+ test "if association is not loaded and child doesn't change and I am saving a grandchild then in memory record should be used" do
+ @ship.parts_attributes=[{:id => @part.id,:trinkets_attributes =>[{:id => @trinket.id, :name => 'Ruby'}]}]
+ assert_equal 1, @ship.parts.proxy_target.size
+ assert_equal 'Mast', @ship.parts[0].name
+ assert_no_difference("@ship.parts[0].trinkets.proxy_target.size") do
+ @ship.parts[0].trinkets.proxy_target.size
+ end
+ assert_equal 'Ruby', @ship.parts[0].trinkets[0].name
+ @ship.save
+ assert_equal 'Ruby', @ship.parts[0].trinkets[0].name
+ end
+
test "when grandchild changed in memory, saving parent should save grandchild" do
@trinket.name = "changed"
@ship.save
diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb
index 4ea5df0945..1cc3a337c3 100644
--- a/activerecord/test/cases/persistence_test.rb
+++ b/activerecord/test/cases/persistence_test.rb
@@ -5,25 +5,19 @@ require 'models/topic'
require 'models/reply'
require 'models/category'
require 'models/company'
-require 'models/customer'
require 'models/developer'
require 'models/project'
-require 'models/default'
-require 'models/auto_id'
-require 'models/column_name'
-require 'models/subscriber'
-require 'models/keyboard'
-require 'models/comment'
require 'models/minimalistic'
require 'models/warehouse_thing'
require 'models/parrot'
+require 'models/minivan'
require 'models/loose_person'
require 'rexml/document'
require 'active_support/core_ext/exception'
class PersistencesTest < ActiveRecord::TestCase
- fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse-things', :authors, :categorizations, :categories, :posts
+ fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse-things', :authors, :categorizations, :categories, :posts, :minivans
def test_create
topic = Topic.new
@@ -220,6 +214,11 @@ class PersistencesTest < ActiveRecord::TestCase
assert !Topic.find(1).approved?
end
+ def test_update_attribute_for_readonly_attribute
+ minivan = Minivan.find('m1')
+ assert_raises(ActiveRecord::ActiveRecordError) { minivan.update_attribute(:color, 'black') }
+ end
+
def test_update_attribute_with_one_changed_and_one_updated
t = Topic.order('id').limit(1).first
title, author_name = t.title, t.author_name
diff --git a/activerecord/test/cases/pk_test.rb b/activerecord/test/cases/primary_keys_test.rb
index 73f4b3848c..1e44237e0a 100644
--- a/activerecord/test/cases/pk_test.rb
+++ b/activerecord/test/cases/primary_keys_test.rb
@@ -13,7 +13,7 @@ class PrimaryKeysTest < ActiveRecord::TestCase
topic = Topic.new
assert topic.to_key.nil?
topic = Topic.find(1)
- assert_equal topic.to_key, [1]
+ assert_equal [1], topic.to_key
end
def test_to_key_with_customized_primary_key
@@ -26,7 +26,7 @@ class PrimaryKeysTest < ActiveRecord::TestCase
def test_to_key_with_primary_key_after_destroy
topic = Topic.find(1)
topic.destroy
- assert_equal topic.to_key, [1]
+ assert_equal [1], topic.to_key
end
def test_integer_key
diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb
index 68abca70b3..f0d97a00d0 100644
--- a/activerecord/test/cases/query_cache_test.rb
+++ b/activerecord/test/cases/query_cache_test.rb
@@ -1,8 +1,6 @@
require "cases/helper"
require 'models/topic'
-require 'models/reply'
require 'models/task'
-require 'models/course'
require 'models/category'
require 'models/post'
diff --git a/activerecord/test/cases/relation_scoping_test.rb b/activerecord/test/cases/relation_scoping_test.rb
index a5a3b3ef38..a50a4d4165 100644
--- a/activerecord/test/cases/relation_scoping_test.rb
+++ b/activerecord/test/cases/relation_scoping_test.rb
@@ -5,6 +5,8 @@ require 'models/developer'
require 'models/project'
require 'models/comment'
require 'models/category'
+require 'models/person'
+require 'models/reference'
class RelationScopingTest < ActiveRecord::TestCase
fixtures :authors, :developers, :projects, :comments, :posts, :developers_projects
@@ -218,7 +220,7 @@ class NestedRelationScopingTest < ActiveRecord::TestCase
end
class HasManyScopingTest< ActiveRecord::TestCase
- fixtures :comments, :posts
+ fixtures :comments, :posts, :people, :references
def setup
@welcome = Post.find(1)
@@ -250,6 +252,23 @@ class HasManyScopingTest< ActiveRecord::TestCase
assert_equal 'a comment...', @welcome.comments.what_are_you
end
end
+
+ def test_should_maintain_default_scope_on_associations
+ person = people(:michael)
+ magician = BadReference.find(1)
+ assert_equal [magician], people(:michael).bad_references
+ end
+
+ def test_should_default_scope_on_associations_is_overriden_by_association_conditions
+ person = people(:michael)
+ assert_equal [], people(:michael).fixed_bad_references
+ end
+
+ def test_should_maintain_default_scope_on_eager_loaded_associations
+ michael = Person.where(:id => people(:michael).id).includes(:bad_references).first
+ magician = BadReference.find(1)
+ assert_equal [magician], michael.bad_references
+ end
end
class HasAndBelongsToManyScopingTest< ActiveRecord::TestCase
@@ -399,4 +418,4 @@ class DefaultScopingTest < ActiveRecord::TestCase
assert_equal nil, PoorDeveloperCalledJamis.create!(:salary => nil).salary
assert_equal 50000, PoorDeveloperCalledJamis.create!(:name => 'David').salary
end
-end \ No newline at end of file
+end
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index ffde8daa07..cb252d56fe 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -1,5 +1,4 @@
require "cases/helper"
-require 'models/tag'
require 'models/tagging'
require 'models/post'
require 'models/topic'
diff --git a/activerecord/test/cases/transaction_callbacks_test.rb b/activerecord/test/cases/transaction_callbacks_test.rb
index df123c9de8..ffc2cd638f 100644
--- a/activerecord/test/cases/transaction_callbacks_test.rb
+++ b/activerecord/test/cases/transaction_callbacks_test.rb
@@ -1,6 +1,5 @@
require "cases/helper"
require 'models/topic'
-require 'models/reply'
class TransactionCallbacksTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false
diff --git a/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb b/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb
index 454e42ed37..628029f8df 100644
--- a/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb
+++ b/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb
@@ -1,6 +1,5 @@
require "cases/helper"
require 'models/topic'
-require 'models/reply'
class I18nGenerateMessageValidationTest < ActiveRecord::TestCase
def setup
diff --git a/activerecord/test/cases/validations_test.rb b/activerecord/test/cases/validations_test.rb
index 3f1b0e333f..fd771ef4be 100644
--- a/activerecord/test/cases/validations_test.rb
+++ b/activerecord/test/cases/validations_test.rb
@@ -4,11 +4,6 @@ require 'models/topic'
require 'models/reply'
require 'models/person'
require 'models/developer'
-require 'models/warehouse_thing'
-require 'models/guid'
-require 'models/owner'
-require 'models/pet'
-require 'models/event'
require 'models/parrot'
require 'models/company'
diff --git a/activerecord/test/cases/xml_serialization_test.rb b/activerecord/test/cases/xml_serialization_test.rb
index 751946ffc5..b11b340e94 100644
--- a/activerecord/test/cases/xml_serialization_test.rb
+++ b/activerecord/test/cases/xml_serialization_test.rb
@@ -2,7 +2,6 @@ require "cases/helper"
require 'models/contact'
require 'models/post'
require 'models/author'
-require 'models/tagging'
require 'models/comment'
require 'models/company_in_module'
diff --git a/activerecord/test/fixtures/minivans.yml b/activerecord/test/fixtures/minivans.yml
index e7a2ab77eb..f1224a4c1a 100644
--- a/activerecord/test/fixtures/minivans.yml
+++ b/activerecord/test/fixtures/minivans.yml
@@ -2,3 +2,4 @@ cool_first:
minivan_id: m1
name: my_minivan
speedometer_id: s1
+ color: blue
diff --git a/activerecord/test/models/country.rb b/activerecord/test/models/country.rb
new file mode 100644
index 0000000000..15e3a1de0b
--- /dev/null
+++ b/activerecord/test/models/country.rb
@@ -0,0 +1,7 @@
+class Country < ActiveRecord::Base
+
+ set_primary_key :country_id
+
+ has_and_belongs_to_many :treaties
+
+end
diff --git a/activerecord/test/models/minivan.rb b/activerecord/test/models/minivan.rb
index c753319a20..602438d16f 100644
--- a/activerecord/test/models/minivan.rb
+++ b/activerecord/test/models/minivan.rb
@@ -3,4 +3,7 @@ class Minivan < ActiveRecord::Base
belongs_to :speedometer
has_one :dashboard, :through => :speedometer
-end \ No newline at end of file
+
+ attr_readonly :color
+
+end
diff --git a/activerecord/test/models/person.rb b/activerecord/test/models/person.rb
index 2a73b1ee01..951ec93c53 100644
--- a/activerecord/test/models/person.rb
+++ b/activerecord/test/models/person.rb
@@ -4,6 +4,8 @@ class Person < ActiveRecord::Base
has_many :posts_with_no_comments, :through => :readers, :source => :post, :include => :comments, :conditions => 'comments.id is null'
has_many :references
+ has_many :bad_references
+ has_many :fixed_bad_references, :conditions => { :favourite => true }, :class_name => 'BadReference'
has_many :jobs, :through => :references
has_one :favourite_reference, :class_name => 'Reference', :conditions => ['favourite=?', true]
has_many :posts_with_comments_sorted_by_comment_id, :through => :readers, :source => :post, :include => :comments, :order => 'comments.id'
diff --git a/activerecord/test/models/reference.rb b/activerecord/test/models/reference.rb
index 479e8b72c6..4a17c936f5 100644
--- a/activerecord/test/models/reference.rb
+++ b/activerecord/test/models/reference.rb
@@ -2,3 +2,8 @@ class Reference < ActiveRecord::Base
belongs_to :person
belongs_to :job
end
+
+class BadReference < ActiveRecord::Base
+ self.table_name ='references'
+ default_scope :conditions => {:favourite => false }
+end
diff --git a/activerecord/test/models/treaty.rb b/activerecord/test/models/treaty.rb
new file mode 100644
index 0000000000..b46537f0d2
--- /dev/null
+++ b/activerecord/test/models/treaty.rb
@@ -0,0 +1,7 @@
+class Treaty < ActiveRecord::Base
+
+ set_primary_key :treaty_id
+
+ has_and_belongs_to_many :countries
+
+end
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index 641726b43f..f3fd37cd61 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -300,6 +300,7 @@ ActiveRecord::Schema.define do
t.string :minivan_id
t.string :name
t.string :speedometer_id
+ t.string :color
end
create_table :minimalistics, :force => true do |t|
@@ -600,6 +601,21 @@ ActiveRecord::Schema.define do
t.string :title
end
+ create_table :countries, :force => true, :id => false, :primary_key => 'country_id' do |t|
+ t.string :country_id
+ t.string :name
+ end
+ create_table :treaties, :force => true, :id => false, :primary_key => 'treaty_id' do |t|
+ t.string :treaty_id
+ t.string :name
+ end
+ create_table :countries_treaties, :force => true, :id => false do |t|
+ t.string :country_id, :null => false
+ t.string :treaty_id, :null => false
+ t.datetime :created_at
+ t.datetime :updated_at
+ end
+
except 'SQLite' do
# fk_test_has_fk should be before fk_test_has_pk
create_table :fk_test_has_fk, :force => true do |t|