From e8c4939fb3366472021c1af1331bfdfe5d7a5d75 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Tue, 9 Dec 2008 11:17:11 -0800 Subject: Benchmark.ms --- activerecord/lib/active_record/base.rb | 4 ++-- .../lib/active_record/connection_adapters/abstract_adapter.rb | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 5d614442c3..a23518b357 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1417,8 +1417,8 @@ module ActiveRecord #:nodoc: def benchmark(title, log_level = Logger::DEBUG, use_silence = true) if logger && logger.level <= log_level result = nil - seconds = Benchmark.realtime { result = use_silence ? silence { yield } : yield } - logger.add(log_level, "#{title} (#{'%.1f' % (seconds * 1000)}ms)") + ms = Benchmark.ms { result = use_silence ? silence { yield } : yield } + logger.add(log_level, '%s (%.1fms)' % [title, ms]) result else yield diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index cab77fc031..bfafcfb3ab 100755 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -160,9 +160,9 @@ module ActiveRecord @open_transactions -= 1 end - def log_info(sql, name, seconds) + def log_info(sql, name, ms) if @logger && @logger.debug? - name = "#{name.nil? ? "SQL" : name} (#{sprintf("%.1f", seconds * 1000)}ms)" + name = '%s (%.1fms)' % [name || 'SQL', ms] @logger.debug(format_log_entry(name, sql.squeeze(' '))) end end @@ -171,9 +171,9 @@ module ActiveRecord def log(sql, name) if block_given? result = nil - seconds = Benchmark.realtime { result = yield } - @runtime += seconds - log_info(sql, name, seconds) + ms = Benchmark.ms { result = yield } + @runtime += ms + log_info(sql, name, ms) result else log_info(sql, name, 0) -- cgit v1.2.3 From 355f41d8aafd75d76db25cdda4736e0052b0605c Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Tue, 9 Dec 2008 20:36:24 +0000 Subject: Rework ActiveSupport::OrderedHash to make lookups faster [#1352 state:committed] Signed-off-by: Jeremy Kemper --- activerecord/test/cases/calculations_test.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'activerecord') diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb index 8bd0dd0f6e..080f6a7007 100644 --- a/activerecord/test/cases/calculations_test.rb +++ b/activerecord/test/cases/calculations_test.rb @@ -171,8 +171,9 @@ class CalculationsTest < ActiveRecord::TestCase Account.expects(:columns).at_least_once.returns([column]) c = Account.count(:all, :group => :firm) - assert_equal Firm, c.first.first.class - assert_equal 1, c.first.last + first_key = c.keys.first + assert_equal Firm, first_key.class + assert_equal 1, c[first_key] end end -- cgit v1.2.3 From 05f2183747c8e75c9e8bbaadb9573b4bdf41ecfc Mon Sep 17 00:00:00 2001 From: Emilio Tagua Date: Tue, 2 Dec 2008 14:12:09 -0300 Subject: Fix: counter_cache should decrement on deleting associated records. [#1195 state:committed] Signed-off-by: Jeremy Kemper --- .../associations/association_collection.rb | 3 +++ .../cases/associations/has_many_associations_test.rb | 20 ++++++++++++++++++++ .../has_many_through_associations_test.rb | 14 ++++++++++++++ 3 files changed, 37 insertions(+) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 0ff91fbdf8..0ad58010b2 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -202,6 +202,9 @@ module ActiveRecord records.each do |record| @target.delete(record) + if respond_to?(:cached_counter_attribute_name) && @owner[cached_counter_attribute_name] + @owner.class.decrement_counter(cached_counter_attribute_name, @owner.send(@owner.class.primary_key)) + end callback(:after_remove, record) end end diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index 816ceb6855..1f8b297e81 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -552,6 +552,18 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal 0, companies(:first_firm).clients_of_firm(true).size end + def test_deleting_updates_counter_cache + post = Post.first + + post.comments.delete(post.comments.first) + post.reload + assert_equal post.comments(true).size, post.comments_count + + post.comments.delete(post.comments.first) + post.reload + assert_equal 0, post.comments_count + end + def test_deleting_before_save new_firm = Firm.new("name" => "A New Firm, Inc.") new_client = new_firm.clients_of_firm.build("name" => "Another Client") @@ -605,6 +617,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end end + def test_clearing_updates_counter_cache + post = Post.first + + post.comments.clear + post.reload + assert_equal 0, post.comments_count + end + def test_clearing_a_dependent_association_collection firm = companies(:first_firm) client_id = firm.dependent_clients_of_firm.first.id 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 a07f4bcbdd..ba3428a508 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -3,6 +3,9 @@ require 'models/post' require 'models/person' require 'models/reader' require 'models/comment' +require 'models/tag' +require 'models/tagging' +require 'models/author' class HasManyThroughAssociationsTest < ActiveRecord::TestCase fixtures :posts, :readers, :people, :comments, :authors @@ -84,6 +87,17 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase assert posts(:welcome).reload.people(true).empty? end + def test_deleting_updates_counter_cache + taggable = Tagging.first.taggable + taggable.taggings.push(Tagging.new) + taggable.reload + assert_equal 1, taggable.taggings_count + + taggable.taggings.delete(taggable.taggings.first) + taggable.reload + assert_equal 0, taggable.taggings_count + end + def test_replace_association assert_queries(4){posts(:welcome);people(:david);people(:michael); posts(:welcome).people(true)} -- cgit v1.2.3 From 953954302682e1ae2f56cfc2ed04debc737c206c Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 10 Dec 2008 11:01:04 -0800 Subject: Add ActiveRecord::VERSION autoload --- activerecord/lib/active_record.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'activerecord') diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index 348e5b94af..1aaf456c0f 100644 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -37,6 +37,8 @@ module ActiveRecord [Base, DynamicFinderMatch, ConnectionAdapters::AbstractAdapter] end + autoload :VERSION, 'active_record/version' + autoload :ActiveRecordError, 'active_record/base' autoload :ConnectionNotEstablished, 'active_record/base' -- cgit v1.2.3 From 96b815d7e81b9cef912ef94c96dca923fe43b0ba Mon Sep 17 00:00:00 2001 From: Emilio Tagua Date: Wed, 10 Dec 2008 16:04:29 -0300 Subject: Fix test names collision. [#1549 state:committed] Signed-off-by: Jeremy Kemper --- activerecord/test/cases/validations_i18n_test.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'activerecord') diff --git a/activerecord/test/cases/validations_i18n_test.rb b/activerecord/test/cases/validations_i18n_test.rb index f59e3f7001..e893a704f1 100644 --- a/activerecord/test/cases/validations_i18n_test.rb +++ b/activerecord/test/cases/validations_i18n_test.rb @@ -506,7 +506,7 @@ class ActiveRecordValidationsI18nTests < ActiveSupport::TestCase # validates_length_of :is w/o mocha - def test_validates_length_of_within_finds_custom_model_key_translation + def test_validates_length_of_is_finds_custom_model_key_translation I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}} I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}} @@ -515,7 +515,7 @@ class ActiveRecordValidationsI18nTests < ActiveSupport::TestCase assert_equal 'custom message', @topic.errors.on(:title) end - def test_validates_length_of_within_finds_global_default_translation + def test_validates_length_of_is_finds_global_default_translation I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}} Topic.validates_length_of :title, :is => 5 @@ -525,7 +525,7 @@ class ActiveRecordValidationsI18nTests < ActiveSupport::TestCase # validates_uniqueness_of w/o mocha - def test_validates_length_of_within_finds_custom_model_key_translation + def test_validates_length_of_is_finds_custom_model_key_translation I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}} I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}} @@ -534,7 +534,7 @@ class ActiveRecordValidationsI18nTests < ActiveSupport::TestCase assert_equal 'custom message', @topic.errors.on(:title) end - def test_validates_length_of_within_finds_global_default_translation + def test_validates_length_of_is_finds_global_default_translation I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}} Topic.validates_length_of :title, :is => 5 -- cgit v1.2.3 From aa5cdb0d47fb5484bfdde8244df7efeb2175bf3a Mon Sep 17 00:00:00 2001 From: Bruce Krysiak Date: Mon, 8 Dec 2008 16:38:04 -0800 Subject: Added a :camelize option to ActiveRecord and Hash to_xml serialization and from_xml deserialization Signed-off-by: Michael Koziarski --- .../active_record/serializers/xml_serializer.rb | 23 +++++++++++++++------- activerecord/test/cases/xml_serialization_test.rb | 7 +++++++ 2 files changed, 23 insertions(+), 7 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/serializers/xml_serializer.rb b/activerecord/lib/active_record/serializers/xml_serializer.rb index d171b742f5..4749823b94 100644 --- a/activerecord/lib/active_record/serializers/xml_serializer.rb +++ b/activerecord/lib/active_record/serializers/xml_serializer.rb @@ -23,11 +23,12 @@ module ActiveRecord #:nodoc: # # # This behavior can be controlled with :only, :except, - # :skip_instruct, :skip_types and :dasherize. + # :skip_instruct, :skip_types, :dasherize and :camelize . # The :only and :except options are the same as for the # +attributes+ method. The default is to dasherize all column names, but you - # can disable this setting :dasherize to +false+. To not have the - # column type included in the XML output set :skip_types to +true+. + # can disable this setting :dasherize to +false+. Setting :camelize + # to +true+ will camelize all column names - this also overrides :dasherize. + # To not have the column type included in the XML output set :skip_types to +true+. # # For instance: # @@ -178,13 +179,22 @@ module ActiveRecord #:nodoc: def root root = (options[:root] || @record.class.to_s.underscore).to_s - dasherize? ? root.dasherize : root + reformat_name(root) end def dasherize? !options.has_key?(:dasherize) || options[:dasherize] end + def camelize? + options.has_key?(:camelize) && options[:camelize] + end + + def reformat_name(name) + name = name.camelize if camelize? + dasherize? ? name.dasherize : name + end + def serializable_attributes serializable_attribute_names.collect { |name| Attribute.new(name, @record) } end @@ -212,7 +222,7 @@ module ActiveRecord #:nodoc: def add_tag(attribute) builder.tag!( - dasherize? ? attribute.name.dasherize : attribute.name, + reformat_name(attribute.name), attribute.value.to_s, attribute.decorations(!options[:skip_types]) ) @@ -220,8 +230,7 @@ module ActiveRecord #:nodoc: def add_associations(association, records, opts) if records.is_a?(Enumerable) - tag = association.to_s - tag = tag.dasherize if dasherize? + tag = reformat_name(association.to_s) if records.empty? builder.tag!(tag, :type => :array) else diff --git a/activerecord/test/cases/xml_serialization_test.rb b/activerecord/test/cases/xml_serialization_test.rb index 63f48865cc..39c6ea820d 100644 --- a/activerecord/test/cases/xml_serialization_test.rb +++ b/activerecord/test/cases/xml_serialization_test.rb @@ -31,6 +31,13 @@ class XmlSerializationTest < ActiveRecord::TestCase assert_match %r{ 'xml_contact', :camelize => true + assert_match %r{^}, @xml + assert_match %r{$}, @xml + assert_match %r{ Date: Wed, 10 Dec 2008 14:48:12 -0800 Subject: Revert "Fix: counter_cache should decrement on deleting associated records." [#1196 state:open] This reverts commit 05f2183747c8e75c9e8bbaadb9573b4bdf41ecfc. --- .../associations/association_collection.rb | 3 --- .../cases/associations/has_many_associations_test.rb | 20 -------------------- .../has_many_through_associations_test.rb | 14 -------------- 3 files changed, 37 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 0ad58010b2..0ff91fbdf8 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -202,9 +202,6 @@ module ActiveRecord records.each do |record| @target.delete(record) - if respond_to?(:cached_counter_attribute_name) && @owner[cached_counter_attribute_name] - @owner.class.decrement_counter(cached_counter_attribute_name, @owner.send(@owner.class.primary_key)) - end callback(:after_remove, record) end end diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index 1f8b297e81..816ceb6855 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -552,18 +552,6 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal 0, companies(:first_firm).clients_of_firm(true).size end - def test_deleting_updates_counter_cache - post = Post.first - - post.comments.delete(post.comments.first) - post.reload - assert_equal post.comments(true).size, post.comments_count - - post.comments.delete(post.comments.first) - post.reload - assert_equal 0, post.comments_count - end - def test_deleting_before_save new_firm = Firm.new("name" => "A New Firm, Inc.") new_client = new_firm.clients_of_firm.build("name" => "Another Client") @@ -617,14 +605,6 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end end - def test_clearing_updates_counter_cache - post = Post.first - - post.comments.clear - post.reload - assert_equal 0, post.comments_count - end - def test_clearing_a_dependent_association_collection firm = companies(:first_firm) client_id = firm.dependent_clients_of_firm.first.id 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 ba3428a508..a07f4bcbdd 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -3,9 +3,6 @@ require 'models/post' require 'models/person' require 'models/reader' require 'models/comment' -require 'models/tag' -require 'models/tagging' -require 'models/author' class HasManyThroughAssociationsTest < ActiveRecord::TestCase fixtures :posts, :readers, :people, :comments, :authors @@ -87,17 +84,6 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase assert posts(:welcome).reload.people(true).empty? end - def test_deleting_updates_counter_cache - taggable = Tagging.first.taggable - taggable.taggings.push(Tagging.new) - taggable.reload - assert_equal 1, taggable.taggings_count - - taggable.taggings.delete(taggable.taggings.first) - taggable.reload - assert_equal 0, taggable.taggings_count - end - def test_replace_association assert_queries(4){posts(:welcome);people(:david);people(:michael); posts(:welcome).people(true)} -- cgit v1.2.3 From 455c7f9e37fda2969e52698b766413fc735eb488 Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Wed, 10 Dec 2008 20:57:19 +0000 Subject: Don't use the transaction instance method so that people with has_one/belongs_to :transaction aren't fubared [#1551 state:committed] Signed-off-by: Jeremy Kemper --- activerecord/lib/active_record/transactions.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb index 27b5aca18f..0a27ea980e 100644 --- a/activerecord/lib/active_record/transactions.rb +++ b/activerecord/lib/active_record/transactions.rb @@ -147,7 +147,7 @@ module ActiveRecord end def save_with_transactions! #:nodoc: - rollback_active_record_state! { transaction { save_without_transactions! } } + rollback_active_record_state! { self.class.transaction { save_without_transactions! } } end # Reset id and @new_record if the transaction rolls back. @@ -175,7 +175,7 @@ module ActiveRecord # instance. def with_transaction_returning_status(method, *args) status = nil - transaction do + self.class.transaction do status = send(method, *args) raise ActiveRecord::Rollback unless status end -- cgit v1.2.3 From a392f34fb4069ab847ff631130d023cdaf896735 Mon Sep 17 00:00:00 2001 From: "Hongli Lai (Phusion)" Date: Mon, 15 Dec 2008 14:47:19 -0600 Subject: Require mocha >= 0.9.3, older versions don't work anymore [#1579 state:resolved] Signed-off-by: Joshua Peek --- activerecord/test/cases/helper.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'activerecord') diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb index 2382bfe4fe..afba715448 100644 --- a/activerecord/test/cases/helper.rb +++ b/activerecord/test/cases/helper.rb @@ -24,6 +24,7 @@ end def uses_mocha(description) require 'rubygems' + gem 'mocha', '>= 0.9.3' require 'mocha' yield rescue LoadError -- cgit v1.2.3 From ed708307137c811d14e5fd2cb4ea550add381a82 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 15 Dec 2008 16:33:31 -0600 Subject: Switch to Rack based session stores. --- activerecord/lib/active_record.rb | 1 + activerecord/lib/active_record/session_store.rb | 319 ++++++++++++++++++++++++ 2 files changed, 320 insertions(+) create mode 100644 activerecord/lib/active_record/session_store.rb (limited to 'activerecord') diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index 1aaf456c0f..c428366a04 100644 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -60,6 +60,7 @@ module ActiveRecord autoload :Schema, 'active_record/schema' autoload :SchemaDumper, 'active_record/schema_dumper' autoload :Serialization, 'active_record/serialization' + autoload :SessionStore, 'active_record/session_store' autoload :TestCase, 'active_record/test_case' autoload :Timestamp, 'active_record/timestamp' autoload :Transactions, 'active_record/transactions' diff --git a/activerecord/lib/active_record/session_store.rb b/activerecord/lib/active_record/session_store.rb new file mode 100644 index 0000000000..bd198c03b2 --- /dev/null +++ b/activerecord/lib/active_record/session_store.rb @@ -0,0 +1,319 @@ +module ActiveRecord + # A session store backed by an Active Record class. A default class is + # provided, but any object duck-typing to an Active Record Session class + # with text +session_id+ and +data+ attributes is sufficient. + # + # The default assumes a +sessions+ tables with columns: + # +id+ (numeric primary key), + # +session_id+ (text, or longtext if your session data exceeds 65K), and + # +data+ (text or longtext; careful if your session data exceeds 65KB). + # The +session_id+ column should always be indexed for speedy lookups. + # Session data is marshaled to the +data+ column in Base64 format. + # If the data you write is larger than the column's size limit, + # ActionController::SessionOverflowError will be raised. + # + # You may configure the table name, primary key, and data column. + # For example, at the end of config/environment.rb: + # ActiveRecord::SessionStore::Session.table_name = 'legacy_session_table' + # ActiveRecord::SessionStore::Session.primary_key = 'session_id' + # ActiveRecord::SessionStore::Session.data_column_name = 'legacy_session_data' + # Note that setting the primary key to the +session_id+ frees you from + # having a separate +id+ column if you don't want it. However, you must + # set session.model.id = session.session_id by hand! A before filter + # on ApplicationController is a good place. + # + # Since the default class is a simple Active Record, you get timestamps + # for free if you add +created_at+ and +updated_at+ datetime columns to + # the +sessions+ table, making periodic session expiration a snap. + # + # You may provide your own session class implementation, whether a + # feature-packed Active Record or a bare-metal high-performance SQL + # store, by setting + # ActiveRecord::SessionStore.session_class = MySessionClass + # You must implement these methods: + # self.find_by_session_id(session_id) + # initialize(hash_of_session_id_and_data) + # attr_reader :session_id + # attr_accessor :data + # save + # destroy + # + # The example SqlBypass class is a generic SQL session store. You may + # use it as a basis for high-performance database-specific stores. + class SessionStore < ActionController::Session::AbstractStore + # The default Active Record class. + class Session < ActiveRecord::Base + ## + # :singleton-method: + # Customizable data column name. Defaults to 'data'. + cattr_accessor :data_column_name + self.data_column_name = 'data' + + before_save :marshal_data! + before_save :raise_on_session_data_overflow! + + class << self + # Don't try to reload ARStore::Session in dev mode. + def reloadable? #:nodoc: + false + end + + def data_column_size_limit + @data_column_size_limit ||= columns_hash[@@data_column_name].limit + end + + # Hook to set up sessid compatibility. + def find_by_session_id(session_id) + setup_sessid_compatibility! + find_by_session_id(session_id) + end + + def marshal(data) + ActiveSupport::Base64.encode64(Marshal.dump(data)) if data + end + + def unmarshal(data) + Marshal.load(ActiveSupport::Base64.decode64(data)) if data + end + + def create_table! + connection.execute <<-end_sql + CREATE TABLE #{table_name} ( + id INTEGER PRIMARY KEY, + #{connection.quote_column_name('session_id')} TEXT UNIQUE, + #{connection.quote_column_name(@@data_column_name)} TEXT(255) + ) + end_sql + end + + def drop_table! + connection.execute "DROP TABLE #{table_name}" + end + + private + # Compatibility with tables using sessid instead of session_id. + def setup_sessid_compatibility! + # Reset column info since it may be stale. + reset_column_information + if columns_hash['sessid'] + def self.find_by_session_id(*args) + find_by_sessid(*args) + end + + define_method(:session_id) { sessid } + define_method(:session_id=) { |session_id| self.sessid = session_id } + else + def self.find_by_session_id(session_id) + find :first, :conditions => ["session_id #{attribute_condition(session_id)}", session_id] + end + end + end + end + + # Lazy-unmarshal session state. + def data + @data ||= self.class.unmarshal(read_attribute(@@data_column_name)) || {} + end + + attr_writer :data + + # Has the session been loaded yet? + def loaded? + !!@data + end + + private + def marshal_data! + return false if !loaded? + write_attribute(@@data_column_name, self.class.marshal(self.data)) + end + + # Ensures that the data about to be stored in the database is not + # larger than the data storage column. Raises + # ActionController::SessionOverflowError. + def raise_on_session_data_overflow! + return false if !loaded? + limit = self.class.data_column_size_limit + if loaded? and limit and read_attribute(@@data_column_name).size > limit + raise ActionController::SessionOverflowError + end + end + end + + # A barebones session store which duck-types with the default session + # store but bypasses Active Record and issues SQL directly. This is + # an example session model class meant as a basis for your own classes. + # + # The database connection, table name, and session id and data columns + # are configurable class attributes. Marshaling and unmarshaling + # are implemented as class methods that you may override. By default, + # marshaling data is + # + # ActiveSupport::Base64.encode64(Marshal.dump(data)) + # + # and unmarshaling data is + # + # Marshal.load(ActiveSupport::Base64.decode64(data)) + # + # This marshaling behavior is intended to store the widest range of + # binary session data in a +text+ column. For higher performance, + # store in a +blob+ column instead and forgo the Base64 encoding. + class SqlBypass + ## + # :singleton-method: + # Use the ActiveRecord::Base.connection by default. + cattr_accessor :connection + + ## + # :singleton-method: + # The table name defaults to 'sessions'. + cattr_accessor :table_name + @@table_name = 'sessions' + + ## + # :singleton-method: + # The session id field defaults to 'session_id'. + cattr_accessor :session_id_column + @@session_id_column = 'session_id' + + ## + # :singleton-method: + # The data field defaults to 'data'. + cattr_accessor :data_column + @@data_column = 'data' + + class << self + def connection + @@connection ||= ActiveRecord::Base.connection + end + + # Look up a session by id and unmarshal its data if found. + def find_by_session_id(session_id) + if record = @@connection.select_one("SELECT * FROM #{@@table_name} WHERE #{@@session_id_column}=#{@@connection.quote(session_id)}") + new(:session_id => session_id, :marshaled_data => record['data']) + end + end + + def marshal(data) + ActiveSupport::Base64.encode64(Marshal.dump(data)) if data + end + + def unmarshal(data) + Marshal.load(ActiveSupport::Base64.decode64(data)) if data + end + + def create_table! + @@connection.execute <<-end_sql + CREATE TABLE #{table_name} ( + id INTEGER PRIMARY KEY, + #{@@connection.quote_column_name(session_id_column)} TEXT UNIQUE, + #{@@connection.quote_column_name(data_column)} TEXT + ) + end_sql + end + + def drop_table! + @@connection.execute "DROP TABLE #{table_name}" + end + end + + attr_reader :session_id + attr_writer :data + + # Look for normal and marshaled data, self.find_by_session_id's way of + # telling us to postpone unmarshaling until the data is requested. + # We need to handle a normal data attribute in case of a new record. + def initialize(attributes) + @session_id, @data, @marshaled_data = attributes[:session_id], attributes[:data], attributes[:marshaled_data] + @new_record = @marshaled_data.nil? + end + + def new_record? + @new_record + end + + # Lazy-unmarshal session state. + def data + unless @data + if @marshaled_data + @data, @marshaled_data = self.class.unmarshal(@marshaled_data) || {}, nil + else + @data = {} + end + end + @data + end + + def loaded? + !!@data + end + + def save + return false if !loaded? + marshaled_data = self.class.marshal(data) + + if @new_record + @new_record = false + @@connection.update <<-end_sql, 'Create session' + INSERT INTO #{@@table_name} ( + #{@@connection.quote_column_name(@@session_id_column)}, + #{@@connection.quote_column_name(@@data_column)} ) + VALUES ( + #{@@connection.quote(session_id)}, + #{@@connection.quote(marshaled_data)} ) + end_sql + else + @@connection.update <<-end_sql, 'Update session' + UPDATE #{@@table_name} + SET #{@@connection.quote_column_name(@@data_column)}=#{@@connection.quote(marshaled_data)} + WHERE #{@@connection.quote_column_name(@@session_id_column)}=#{@@connection.quote(session_id)} + end_sql + end + end + + def destroy + unless @new_record + @@connection.delete <<-end_sql, 'Destroy session' + DELETE FROM #{@@table_name} + WHERE #{@@connection.quote_column_name(@@session_id_column)}=#{@@connection.quote(session_id)} + end_sql + end + end + end + + # The class used for session storage. Defaults to + # ActiveRecord::SessionStore::Session + cattr_accessor :session_class + self.session_class = Session + + SESSION_RECORD_KEY = 'rack.session.record'.freeze + + private + def get_session(env, sid) + Base.silence do + sid ||= generate_sid + session = @@session_class.find_by_session_id(sid) + session ||= @@session_class.new(:session_id => sid, :data => {}) + env[SESSION_RECORD_KEY] = session + [sid, session.data] + end + end + + def set_session(env, sid, session_data) + Base.silence do + record = env[SESSION_RECORD_KEY] + record.data = session_data + return false unless record.save + + session_data = record.data + if session_data && session_data.respond_to?(:each_value) + session_data.each_value do |obj| + obj.clear_association_cache if obj.respond_to?(:clear_association_cache) + end + end + end + + return true + end + end +end -- cgit v1.2.3 From 46c7dd234807b2d24c8c742acb18c633b69e385d Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Wed, 10 Dec 2008 00:53:32 +0100 Subject: normalize author names in changelogs [#1495 state:committed] Signed-off-by: David Heinemeier Hansson --- activerecord/CHANGELOG | 784 ++++++++++++++++++++++++------------------------- 1 file changed, 392 insertions(+), 392 deletions(-) (limited to 'activerecord') diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 423a0bd0cc..d057ddfcd0 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -2,7 +2,7 @@ * I18n the word separator for error messages. Introduces the activerecord.errors.format.separator translation key. #1294 [Akira Matsuda] -* Add :having as a key to find and the relevant associations. [miloops] +* Add :having as a key to find and the relevant associations. [Emilio Tagua] * Added default_scope to Base #1381 [Paweł Kondzior]. Example: @@ -29,19 +29,19 @@ * Skip collection ids reader optimization if using :finder_sql [Jeremy Kemper] -* Add Model#delete instance method, similar to Model.delete class method. #1086 [Hongli Lai] +* Add Model#delete instance method, similar to Model.delete class method. #1086 [Hongli Lai (Phusion)] * MySQL: cope with quirky default values for not-null text columns. #1043 [Frederick Cheung] * Multiparameter attributes skip time zone conversion for time-only columns [#1030 state:resolved] [Geoff Buesing] -* Base.skip_time_zone_conversion_for_attributes uses class_inheritable_accessor, so that subclasses don't overwrite Base [#346 state:resolved] [miloops] +* Base.skip_time_zone_conversion_for_attributes uses class_inheritable_accessor, so that subclasses don't overwrite Base [#346 state:resolved] [Emilio Tagua] -* Added find_last_by dynamic finder #762 [miloops] +* Added find_last_by dynamic finder #762 [Emilio Tagua] -* Internal API: configurable association options and build_association method for reflections so plugins may extend and override. #985 [Hongli Lai] +* Internal API: configurable association options and build_association method for reflections so plugins may extend and override. #985 [Hongli Lai (Phusion)] -* Changed benchmarks to be reported in milliseconds [DHH] +* Changed benchmarks to be reported in milliseconds [David Heinemeier Hansson] * Connection pooling. #936 [Nick Sieger] @@ -90,7 +90,7 @@ *2.1.0 (May 31st, 2008)* -* Add ActiveRecord::Base.sti_name that checks ActiveRecord::Base#store_full_sti_class? and returns either the full or demodulized name. [rick] +* Add ActiveRecord::Base.sti_name that checks ActiveRecord::Base#store_full_sti_class? and returns either the full or demodulized name. [Rick Olson] * Add first/last methods to associations/named_scope. Resolved #226. [Ryan Bates] @@ -123,27 +123,27 @@ * Fixed that change_column should be able to use :null => true on a field that formerly had false [Nate Wiger] [#26] -* Added that the MySQL adapter should map integer to either smallint, int, or bigint depending on the :limit just like PostgreSQL [DHH] +* Added that the MySQL adapter should map integer to either smallint, int, or bigint depending on the :limit just like PostgreSQL [David Heinemeier Hansson] -* Change validates_uniqueness_of :case_sensitive option default back to true (from [9160]). Love your database columns, don't LOWER them. [rick] +* Change validates_uniqueness_of :case_sensitive option default back to true (from [9160]). Love your database columns, don't LOWER them. [Rick Olson] -* Add support for interleaving migrations by storing which migrations have run in the new schema_migrations table. Closes #11493 [jordi] +* Add support for interleaving migrations by storing which migrations have run in the new schema_migrations table. Closes #11493 [Jordi Bunster] -* ActiveRecord::Base#sum defaults to 0 if no rows are returned. Closes #11550 [kamal] +* ActiveRecord::Base#sum defaults to 0 if no rows are returned. Closes #11550 [Kamal Fariz Mahyuddin] -* Ensure that respond_to? considers dynamic finder methods. Closes #11538. [floehopper] +* Ensure that respond_to? considers dynamic finder methods. Closes #11538. [James Mead] -* Ensure that save on parent object fails for invalid has_one association. Closes #10518. [Pratik] +* Ensure that save on parent object fails for invalid has_one association. Closes #10518. [Pratik Naik] -* Remove duplicate code from associations. [Pratik] +* Remove duplicate code from associations. [Pratik Naik] -* Refactor HasManyThroughAssociation to inherit from HasManyAssociation. Association callbacks and _ids= now work with hm:t. #11516 [rubyruy] +* Refactor HasManyThroughAssociation to inherit from HasManyAssociation. Association callbacks and _ids= now work with hm:t. #11516 [Ruy Asan] -* Ensure HABTM#create and HABTM#build do not load entire association. [Pratik] +* Ensure HABTM#create and HABTM#build do not load entire association. [Pratik Naik] * Improve documentation. [Xavier Noria, Jack Danger Canty, leethal] -* Tweak ActiveRecord::Base#to_json to include a root value in the returned hash: {"post": {"title": ...}} [rick] +* Tweak ActiveRecord::Base#to_json to include a root value in the returned hash: {"post": {"title": ...}} [Rick Olson] Post.find(1).to_json # => {"title": ...} config.active_record.include_root_in_json = true @@ -151,9 +151,9 @@ * Add efficient #include? to AssociationCollection (for has_many/has_many :through/habtm). [stopdropandrew] -* PostgreSQL: create_ and drop_database support. #9042 [ez, pedz, nicksieger] +* PostgreSQL: create_ and drop_database support. #9042 [ez, pedz, Nick Sieger] -* Ensure that validates_uniqueness_of works with with_scope. Closes #9235. [nik.wakelin, cavalle] +* Ensure that validates_uniqueness_of works with with_scope. Closes #9235. [Nik Wakelin, cavalle] * Partial updates include only unsaved attributes. Off by default; set YourClass.partial_updates = true to enable. [Jeremy Kemper] @@ -163,21 +163,21 @@ * Track changes to unsaved attributes. [Jeremy Kemper] -* Switched to UTC-timebased version numbers for migrations and the schema. This will as good as eliminate the problem of multiple migrations getting the same version assigned in different branches. Also added rake db:migrate:up/down to apply individual migrations that may need to be run when you merge branches #11458 [jbarnette] +* Switched to UTC-timebased version numbers for migrations and the schema. This will as good as eliminate the problem of multiple migrations getting the same version assigned in different branches. Also added rake db:migrate:up/down to apply individual migrations that may need to be run when you merge branches #11458 [John Barnette] -* Fixed that has_many :through would ignore the hash conditions #11447 [miloops] +* Fixed that has_many :through would ignore the hash conditions #11447 [Emilio Tagua] * Fix issue where the :uniq option of a has_many :through association is ignored when find(:all) is called. Closes #9407 [cavalle] * Fix duplicate table alias error when including an association with a has_many :through association on the same join table. Closes #7310 [cavalle] -* More efficient association preloading code that compacts a through_records array in a central location. Closes #11427 [danger] +* More efficient association preloading code that compacts a through_records array in a central location. Closes #11427 [Jack Danger Canty] -* Improve documentation. [Radar, Jan De Poorter, chuyeow, xaviershay, danger, miloops, Xavier Noria, Sunny Ripert] +* Improve documentation. [Ryan Bigg, Jan De Poorter, Cheah Chu Yeow, Xavier Shay, Jack Danger Canty, Emilio Tagua, Xavier Noria, Sunny Ripert] -* Fixed that ActiveRecord#Base.find_or_create/initialize would not honor attr_protected/accessible when used with a hash #11422 [miloops] +* Fixed that ActiveRecord#Base.find_or_create/initialize would not honor attr_protected/accessible when used with a hash #11422 [Emilio Tagua] -* Added ActiveRecord#Base.all/first/last as aliases for find(:all/:first/:last) #11413 [nkallen, thechrisoshow] +* Added ActiveRecord#Base.all/first/last as aliases for find(:all/:first/:last) #11413 [nkallen, Chris O'Sullivan] * Merge the has_finder gem, renamed as 'named_scope'. #11404 [nkallen] @@ -193,25 +193,25 @@ See http://pivots.pivotallabs.com/users/nick/blog/articles/284-hasfinder-it-s-now-easier-than-ever-to-create-complex-re-usable-sql-queries -* Add has_one :through support. #4756 [thechrisoshow] +* Add has_one :through support. #4756 [Chris O'Sullivan] -* Migrations: create_table supports primary_key_prefix_type. #10314 [student, thechrisoshow] +* Migrations: create_table supports primary_key_prefix_type. #10314 [student, Chris O'Sullivan] * Added logging for dependency load errors with fixtures #11056 [stuthulhu] * Time zone aware attributes use Time#in_time_zone [Geoff Buesing] -* Fixed that scoped joins would not always be respected #6821 [Theory/Danger] +* Fixed that scoped joins would not always be respected #6821 [Theory/Jack Danger Canty] * Ensure that ActiveRecord::Calculations disambiguates field names with the table name. #11027 [cavalle] * Added add/remove_timestamps to the schema statements for adding the created_at/updated_at columns on existing tables #11129 [jramirez] -* Added ActiveRecord::Base.find(:last) #11338 [miloops] +* Added ActiveRecord::Base.find(:last) #11338 [Emilio Tagua] * test_native_types expects DateTime.local_offset instead of DateTime.now.offset; fixes test breakage due to dst transition [Geoff Buesing] -* Add :readonly option to HasManyThrough associations. #11156 [miloops] +* Add :readonly option to HasManyThrough associations. #11156 [Emilio Tagua] * Improve performance on :include/:conditions/:limit queries by selectively joining in the pre-query. #9560 [dasil003] @@ -231,7 +231,7 @@ * Optimise the BigDecimal conversion code. #11110 [adymo] -* Introduce the :readonly option to all associations. Records from the association cannot be saved. #11084 [miloops] +* Introduce the :readonly option to all associations. Records from the association cannot be saved. #11084 [Emilio Tagua] * Multiparameter attributes for time columns fail over to DateTime when out of range of Time [Geoff Buesing] @@ -239,15 +239,15 @@ * Add timezone-aware attribute readers and writers. #10982 [Geoff Buesing] -* Instantiating time objects in multiparameter attributes uses Time.zone if available. #10982 [rick] +* Instantiating time objects in multiparameter attributes uses Time.zone if available. #10982 [Rick Olson] -* Add note about how ActiveRecord::Observer classes are initialized in a Rails app. #10980 [fxn] +* Add note about how ActiveRecord::Observer classes are initialized in a Rails app. #10980 [Xavier Noria] * MySQL: omit text/blob defaults from the schema instead of using an empty string. #10963 [mdeiters] * belongs_to supports :dependent => :destroy and :delete. #10592 [Jonathan Viney] -* Introduce preload query strategy for eager :includes. #9640 [Frederick Cheung, Aleksey Kondratenko, codafoo] +* Introduce preload query strategy for eager :includes. #9640 [Frederick Cheung, Aliaksey Kandratsenka, codafoo] * Support aggregations in finder conditions. #10572 [Ryan Kinderman] @@ -263,13 +263,13 @@ * update_all ignores scoped :order and :limit, so post.comments.update_all doesn't try to include the comment order in the update statement. #10686 [Brendan Ribera] -* Added ActiveRecord::Base.cache_key to make it easier to cache Active Records in combination with the new ActiveSupport::Cache::* libraries [DHH] +* Added ActiveRecord::Base.cache_key to make it easier to cache Active Records in combination with the new ActiveSupport::Cache::* libraries [David Heinemeier Hansson] * Make sure CSV fixtures are compatible with ruby 1.9's new csv implementation. [JEG2] * Added by parameter to increment, decrement, and their bang varieties so you can do player1.increment!(:points, 5) #10542 [Sam] -* Optimize ActiveRecord::Base#exists? to use #select_all instead of #find. Closes #10605 [jamesh, fcheung, protocool] +* Optimize ActiveRecord::Base#exists? to use #select_all instead of #find. Closes #10605 [jamesh, Frederick Cheung, protocool] * Don't unnecessarily load has_many associations in after_update callbacks. Closes #6822 [stopdropandrew, canadaduane] @@ -282,11 +282,11 @@ *2.0.2* (December 16th, 2007) -* Ensure optimistic locking handles nil #lock_version values properly. Closes #10510 [rick] +* Ensure optimistic locking handles nil #lock_version values properly. Closes #10510 [Rick Olson] * Make the Fixtures Test::Unit enhancements more supporting for double-loaded test cases. Closes #10379 [brynary] -* Fix that validates_acceptance_of still works for non-existent tables (useful for bootstrapping new databases). Closes #10474 [hasmanyjosh] +* Fix that validates_acceptance_of still works for non-existent tables (useful for bootstrapping new databases). Closes #10474 [Josh Susser] * Ensure that the :uniq option for has_many :through associations retains the order. #10463 [remvee] @@ -297,19 +297,19 @@ *2.0.1* (December 7th, 2007) -* Removed query cache rescue as it could cause code to be run twice (closes #10408) [DHH] +* Removed query cache rescue as it could cause code to be run twice (closes #10408) [David Heinemeier Hansson] *2.0.0* (December 6th, 2007) * Anchor DateTimeTest to fixed DateTime instead of a variable value based on Time.now#advance#to_datetime, so that this test passes on 64-bit platforms running Ruby 1.8.6+ [Geoff Buesing] -* Fixed that the Query Cache should just be ignored if the database is misconfigured (so that the "About your applications environment" works even before the database has been created) [DHH] +* Fixed that the Query Cache should just be ignored if the database is misconfigured (so that the "About your applications environment" works even before the database has been created) [David Heinemeier Hansson] * Fixed that the truncation of strings longer than 50 chars should use inspect so newlines etc are escaped #10385 [Norbert Crombach] -* Fixed that habtm associations should be able to set :select as part of their definition and have that honored [DHH] +* Fixed that habtm associations should be able to set :select as part of their definition and have that honored [David Heinemeier Hansson] * Document how the :include option can be used in Calculations::calculate. Closes #7446 [adamwiggins, ultimoamore] @@ -319,7 +319,7 @@ so newlines etc are escaped #10385 [Norbert Crombach] * More complete documentation for find_by_sql. Closes #7912 [fearoffish] -* Added ActiveRecord::Base#becomes to turn a record into one of another class (mostly relevant for STIs) [DHH]. Example: +* Added ActiveRecord::Base#becomes to turn a record into one of another class (mostly relevant for STIs) [David Heinemeier Hansson]. Example: render :partial => @client.becomes(Company) # renders companies/company instead of clients/client @@ -345,25 +345,25 @@ so newlines etc are escaped #10385 [Norbert Crombach] * attr_readonly behaves well with optimistic locking. #10188 [Nick Bugajski] -* Base#to_xml supports the nil="true" attribute like Hash#to_xml. #8268 [Catfish] +* Base#to_xml supports the nil="true" attribute like Hash#to_xml. #8268 [Jonathan del Strother] -* Change plings to the more conventional quotes in the documentation. Closes #10104 [danger] +* Change plings to the more conventional quotes in the documentation. Closes #10104 [Jack Danger Canty] -* Fix HasManyThrough Association so it uses :conditions on the HasMany Association. Closes #9729 [danger] +* Fix HasManyThrough Association so it uses :conditions on the HasMany Association. Closes #9729 [Jack Danger Canty] * Ensure that column names are quoted. Closes #10134 [wesley.moxam] -* Smattering of grammatical fixes to documentation. Closes #10083 [BobSilva] +* Smattering of grammatical fixes to documentation. Closes #10083 [Bob Silva] -* Enhance explanation with more examples for attr_accessible macro. Closes #8095 [fearoffish, Marcel Molina] +* Enhance explanation with more examples for attr_accessible macro. Closes #8095 [fearoffish, Marcel Molina Jr.] * Update association/method mapping table to refected latest collection methods for has_many :through. Closes #8772 [Pratik Naik] -* Explain semantics of having several different AR instances in a transaction block. Closes #9036 [jacobat, Marcel Molina] +* Explain semantics of having several different AR instances in a transaction block. Closes #9036 [jacobat, Marcel Molina Jr.] -* Update Schema documentation to use updated sexy migration notation. Closes #10086 [sjgman9] +* Update Schema documentation to use updated sexy migration notation. Closes #10086 [Sam Granieri] -* Make fixtures work with the new test subclasses. [Tarmo Tänav, Koz] +* Make fixtures work with the new test subclasses. [Tarmo Tänav, Michael Koziarski] * Introduce finder :joins with associations. Same :include syntax but with inner rather than outer joins. #10012 [RubyRedRick] # Find users with an avatar @@ -374,7 +374,7 @@ so newlines etc are escaped #10385 [Norbert Crombach] * Associations: speedup duplicate record check. #10011 [Pratik Naik] -* Make sure that << works on has_many associations on unsaved records. Closes #9989 [hasmanyjosh] +* Make sure that << works on has_many associations on unsaved records. Closes #9989 [Josh Susser] * Allow association redefinition in subclasses. #9346 [wildchild] @@ -397,7 +397,7 @@ so newlines etc are escaped #10385 [Norbert Crombach] * Use VALID_FIND_OPTIONS when resolving :find scoping rather than hard coding the list of valid find options. Closes #9443 [sur] -* Limited eager loading no longer ignores scoped :order. Closes #9561 [danger, Josh Peek] +* Limited eager loading no longer ignores scoped :order. Closes #9561 [Jack Danger Canty, Josh Peek] * Assigning an instance of a foreign class to a composed_of aggregate calls an optional conversion block. Refactor and simplify composed_of implementation. #6322 [brandon, Chris Cruft] @@ -410,7 +410,7 @@ so newlines etc are escaped #10385 [Norbert Crombach] * Complete the assimilation of Sexy Migrations from ErrFree [Chris Wanstrath, PJ Hyett] http://errtheblog.com/post/2381 -* Qualified column names work in hash conditions, like :conditions => { 'comments.created_at' => ... }. #9733 [danger] +* Qualified column names work in hash conditions, like :conditions => { 'comments.created_at' => ... }. #9733 [Jack Danger Canty] * Fix regression where the association would not construct new finder SQL on save causing bogus queries for "WHERE owner_id = NULL" even after owner was saved. #8713 [Bryan Helmkamp] @@ -420,11 +420,11 @@ so newlines etc are escaped #10385 [Norbert Crombach] * Alias association #build to #new so it behaves predictably. #8787 [Pratik Naik] -* Add notes to documentation regarding attr_readonly behavior with counter caches and polymorphic associations. Closes #9835 [saimonmoore, rick] +* Add notes to documentation regarding attr_readonly behavior with counter caches and polymorphic associations. Closes #9835 [saimonmoore, Rick Olson] * Observers can observe model names as symbols properly now. Closes #9869 [queso] -* find_and_(initialize|create)_by methods can now properly initialize protected attributes [Tobias Luetke] +* find_and_(initialize|create)_by methods can now properly initialize protected attributes [Tobias Lütke] * belongs_to infers the foreign key from the association name instead of from the class name. [Jeremy Kemper] @@ -443,16 +443,16 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea * Allow change_column to set NOT NULL in the PostgreSQL adapter [Tarmo Tänav] -* Fix that ActiveRecord would create attribute methods and override custom attribute getters if the method is also defined in Kernel.methods. [Rick] +* Fix that ActiveRecord would create attribute methods and override custom attribute getters if the method is also defined in Kernel.methods. [Rick Olson] -* Don't call attr_readonly on polymorphic belongs_to associations, in case it matches the name of some other non-ActiveRecord class/module. [Rick] +* Don't call attr_readonly on polymorphic belongs_to associations, in case it matches the name of some other non-ActiveRecord class/module. [Rick Olson] * Try loading activerecord--adapter gem before trying a plain require so you can use custom gems for the bundled adapters. Also stops gems from requiring an adapter from an old Active Record gem. [Jeremy Kemper, Derrick Spell] *2.0.0 [Preview Release]* (September 29th, 2007) [Includes duplicates of changes from 1.14.2 - 1.15.3] -* Add attr_readonly to specify columns that are skipped during a normal ActiveRecord #save operation. Closes #6896 [dcmanges] +* Add attr_readonly to specify columns that are skipped during a normal ActiveRecord #save operation. Closes #6896 [Dan Manges] class Comment < ActiveRecord::Base # Automatically sets Article#comments_count as readonly. @@ -463,7 +463,7 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea attr_readonly :approved_comments_count end -* Make size for has_many :through use counter cache if it exists. Closes #9734 [xaviershay] +* Make size for has_many :through use counter cache if it exists. Closes #9734 [Xavier Shay] * Remove DB2 adapter since IBM chooses to maintain their own adapter instead. [Jeremy Kemper] @@ -479,9 +479,9 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea * Added the possibility of using symbols in addition to concrete classes with ActiveRecord::Observer#observe. #3998 [Robby Russell, Tarmo Tänav] -* Added ActiveRecord::Base#to_json/from_json [DHH, Cheah Chu Yeow] +* Added ActiveRecord::Base#to_json/from_json [David Heinemeier Hansson, Cheah Chu Yeow] -* Added ActiveRecord::Base#from_xml [DHH]. Example: +* Added ActiveRecord::Base#from_xml [David Heinemeier Hansson]. Example: xml = "David" Person.new.from_xml(xml).name # => "David" @@ -516,27 +516,27 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea * Explicitly require active_record/query_cache before using it. [Jeremy Kemper] -* Fix bug where unserializing an attribute attempts to modify a frozen @attributes hash for a deleted record. [Rick, marclove] +* Fix bug where unserializing an attribute attempts to modify a frozen @attributes hash for a deleted record. [Rick Olson, marclove] * Performance: absorb instantiate and initialize_with_callbacks into the Base methods. [Jeremy Kemper] -* Fixed that eager loading queries and with_scope should respect the :group option [DHH] +* Fixed that eager loading queries and with_scope should respect the :group option [David Heinemeier Hansson] * Improve performance and functionality of the postgresql adapter. Closes #8049 [roderickvd] For more information see: http://dev.rubyonrails.org/ticket/8049 -* Don't clobber includes passed to has_many.count [danger] +* Don't clobber includes passed to has_many.count [Jack Danger Canty] -* Make sure has_many uses :include when counting [danger] +* Make sure has_many uses :include when counting [Jack Danger Canty] -* Change the implementation of ActiveRecord's attribute reader and writer methods [nzkoz] +* Change the implementation of ActiveRecord's attribute reader and writer methods [Michael Koziarski] - Generate Reader and Writer methods which cache attribute values in hashes. This is to avoid repeatedly parsing the same date or integer columns. - Change exception raised when users use find with :select then try to access a skipped column. Plugins could override missing_attribute() to lazily load the columns. - Move method definition to the class, instead of the instance - Always generate the readers, writers and predicate methods. -* Perform a deep #dup on query cache results so that modifying activerecord attributes does not modify the cached attributes. [Rick] +* Perform a deep #dup on query cache results so that modifying activerecord attributes does not modify the cached attributes. [Rick Olson] # Ensure that has_many :through associations use a count query instead of loading the target when #size is called. Closes #8800 [Pratik Naik] @@ -556,7 +556,7 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea * Remove deprecated count(conditions=nil, joins=nil) usage. Closes #8993 [Pratik Naik] -* Change belongs_to so that the foreign_key assumption is taken from the association name, not the class name. Closes #8992 [hasmanyjosh] +* Change belongs_to so that the foreign_key assumption is taken from the association name, not the class name. Closes #8992 [Josh Susser] OLD belongs_to :visitor, :class_name => 'User' # => inferred foreign_key is user_id @@ -570,7 +570,7 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea * Move from select * to select tablename.* to avoid clobbering IDs. Closes #8889 [dasil003] -* Don't call unsupported methods on associated objects when using :include, :method with to_xml #7307, [manfred, jwilger] +* Don't call unsupported methods on associated objects when using :include, :method with to_xml #7307, [Manfred Stienstra, jwilger] * Define collection singular ids method for has_many :through associations. #8763 [Pratik Naik] @@ -584,7 +584,7 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea * Update tests' use of fixtures for the new collections api. #8726 [Kamal Fariz Mahyuddin] -* Save associated records only if the association is already loaded. #8713 [blaine] +* Save associated records only if the association is already loaded. #8713 [Blaine] * MySQL: fix show_variable. #8448 [matt, Jeremy Kemper] @@ -628,7 +628,7 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea * Load database adapters on demand. Eliminates config.connection_adapters and RAILS_CONNECTION_ADAPTERS. Add your lib directory to the $LOAD_PATH and put your custom adapter in lib/active_record/connection_adapters/adaptername_adapter.rb. This way you can provide custom adapters as plugins or gems without modifying Rails. [Jeremy Kemper] -* Ensure that associations with :dependent => :delete_all respect :conditions option. Closes #8034 [danger, Josh Peek, Rick] +* Ensure that associations with :dependent => :delete_all respect :conditions option. Closes #8034 [Jack Danger Canty, Josh Peek, Rick Olson] * belongs_to assignment creates a new proxy rather than modifying its target in-place. #8412 [mmangino@elevatedrails.com] @@ -640,13 +640,13 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea * Sanitize Base#inspect. #8392, #8623 [Nik Wakelin, jnoon] -* Replace the transaction {|transaction|..} semantics with a new Exception ActiveRecord::Rollback. [Koz] +* Replace the transaction {|transaction|..} semantics with a new Exception ActiveRecord::Rollback. [Michael Koziarski] * Oracle: extract column length for CHAR also. #7866 [ymendel] * Document :allow_nil option for validates_acceptance_of since it defaults to true. [tzaharia] -* Update documentation for :dependent declaration so that it explicitly uses the non-deprecated API. [danger] +* Update documentation for :dependent declaration so that it explicitly uses the non-deprecated API. [Jack Danger Canty] * Add documentation caveat about when to use count_by_sql. [fearoffish] @@ -656,7 +656,7 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea * Add documentation for :encoding option to mysql adapter. [marclove] -* Added short-hand declaration style to migrations (inspiration from Sexy Migrations, http://errtheblog.com/post/2381) [DHH]. Example: +* Added short-hand declaration style to migrations (inspiration from Sexy Migrations, http://errtheblog.com/post/2381) [David Heinemeier Hansson]. Example: create_table "products" do |t| t.column "shop_id", :integer @@ -675,17 +675,17 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea t.timestamps end -* Use association name for the wrapper element when using .to_xml. Previous behavior lead to non-deterministic situations with STI and polymorphic associations. [Koz, jstrachan] +* Use association name for the wrapper element when using .to_xml. Previous behavior lead to non-deterministic situations with STI and polymorphic associations. [Michael Koziarski, jstrachan] * Improve performance of calling .create on has_many :through associations. [evan] * Improved cloning performance by relying less on exception raising #8159 [Blaine] -* Added ActiveRecord::Base.inspect to return a column-view like # [DHH] +* Added ActiveRecord::Base.inspect to return a column-view like # [David Heinemeier Hansson] -* Added yielding of Builder instance for ActiveRecord::Base#to_xml calls [DHH] +* Added yielding of Builder instance for ActiveRecord::Base#to_xml calls [David Heinemeier Hansson] -* Small additions and fixes for ActiveRecord documentation. Closes #7342 [jeremymcanally] +* Small additions and fixes for ActiveRecord documentation. Closes #7342 [Jeremy McAnally] * Add helpful debugging info to the ActiveRecord::StatementInvalid exception in ActiveRecord::ConnectionAdapters::SqliteAdapter#table_structure. Closes #7925. [court3nay] @@ -695,13 +695,13 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea * Base.update_all :order and :limit options. Useful for MySQL updates that must be ordered to avoid violating unique constraints. [Jeremy Kemper] -* Remove deprecated object transactions. People relying on this functionality should install the object_transactions plugin at http://code.bitsweat.net/svn/object_transactions. Closes #5637 [Koz, Jeremy Kemper] +* Remove deprecated object transactions. People relying on this functionality should install the object_transactions plugin at http://code.bitsweat.net/svn/object_transactions. Closes #5637 [Michael Koziarski, Jeremy Kemper] * PostgreSQL: remove DateTime -> Time downcast. Warning: do not enable translate_results for the C bindings if you have timestamps outside Time's domain. [Jeremy Kemper] * find_or_create_by_* takes a hash so you can create with more attributes than are in the method name. For example, Person.find_or_create_by_name(:name => 'Henry', :comments => 'Hi new user!') is equivalent to Person.find_by_name('Henry') || Person.create(:name => 'Henry', :comments => 'Hi new user!'). #7368 [Josh Susser] -* Make sure with_scope takes both :select and :joins into account when setting :readonly. Allows you to save records you retrieve using method_missing on a has_many :through associations. [Koz] +* Make sure with_scope takes both :select and :joins into account when setting :readonly. Allows you to save records you retrieve using method_missing on a has_many :through associations. [Michael Koziarski] * Allow a polymorphic :source for has_many :through associations. Closes #7143 [protocool] @@ -726,13 +726,13 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea * Test DateTime native type in migrations, including an edge case with dates during calendar reform. #7649, #7724 [fedot, Geoff Buesing] -* SQLServer: correctly schema-dump tables with no indexes or descending indexes. #7333, #7703 [Jakob S, Tom Ward] +* SQLServer: correctly schema-dump tables with no indexes or descending indexes. #7333, #7703 [Jakob Skjerning, Tom Ward] * SQLServer: recognize real column type as Ruby float. #7057 [sethladd, Tom Ward] -* Added fixtures :all as a way of loading all fixtures in the fixture directory at once #7214 [manfred] +* Added fixtures :all as a way of loading all fixtures in the fixture directory at once #7214 [Manfred Stienstra] -* Added database connection as a yield parameter to ActiveRecord::Base.transaction so you can manually rollback [DHH]. Example: +* Added database connection as a yield parameter to ActiveRecord::Base.transaction so you can manually rollback [David Heinemeier Hansson]. Example: transaction do |transaction| david.withdrawal(100) @@ -742,14 +742,14 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Made increment_counter/decrement_counter play nicely with optimistic locking, and added a more general update_counters method [Jamis Buck] -* Reworked David's query cache to be available as Model.cache {...}. For the duration of the block no select query should be run more then once. Any inserts/deletes/executes will flush the whole cache however [Tobias Luetke] +* Reworked David's query cache to be available as Model.cache {...}. For the duration of the block no select query should be run more then once. Any inserts/deletes/executes will flush the whole cache however [Tobias Lütke] Task.cache { Task.find(1); Task.find(1) } #=> 1 query * When dealing with SQLite3, use the table_info pragma helper, so that the bindings can do some translation for when sqlite3 breaks incompatibly between point releases. [Jamis Buck] * Oracle: fix lob and text default handling. #7344 [gfriedrich, Michael Schoen] -* SQLServer: don't choke on strings containing 'null'. #7083 [Jakob S] +* SQLServer: don't choke on strings containing 'null'. #7083 [Jakob Skjerning] * MySQL: blob and text columns may not have defaults in 5.x. Update fixtures schema for strict mode. #6695 [Dan Kubb] @@ -759,7 +759,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Use Date#to_s(:db) for quoted dates. #7411 [Michael Schoen] -* Don't create instance writer methods for class attributes. Closes #7401 [Rick] +* Don't create instance writer methods for class attributes. Closes #7401 [Rick Olson] * Docs: validations examples. #7343 [zackchandler] @@ -779,11 +779,11 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Make sure sqlite3 driver closes open connections on disconnect [Rob Rasmussen] -* [DOC] clear up some ambiguity with the way has_and_belongs_to_many creates the default join table name. #7072 [jeremymcanally] +* [DOC] clear up some ambiguity with the way has_and_belongs_to_many creates the default join table name. #7072 [Jeremy McAnally] * change_column accepts :default => nil. Skip column options for primary keys. #6956, #7048 [Dan Manges, Jeremy Kemper] -* MySQL, PostgreSQL: change_column_default quotes the default value and doesn't lose column type information. #3987, #6664 [Jonathan Viney, manfred, altano@bigfoot.com] +* MySQL, PostgreSQL: change_column_default quotes the default value and doesn't lose column type information. #3987, #6664 [Jonathan Viney, Manfred Stienstra, altano@bigfoot.com] * Oracle: create_table takes a :sequence_name option to override the 'tablename_seq' default. #7000 [Michael Schoen] @@ -818,15 +818,15 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * fix faulty inheritance tests and that eager loading grabs the wrong inheritance column when the class of your association is an STI subclass. Closes #6859 [protocool] -* Consolidated different create and create! versions to call through to the base class with scope. This fixes inconsistencies, especially related to protected attribtues. Closes #5847 [Alexander Dymo, Tobias Luetke] +* Consolidated different create and create! versions to call through to the base class with scope. This fixes inconsistencies, especially related to protected attribtues. Closes #5847 [Alexander Dymo, Tobias Lütke] * find supports :lock with :include. Check whether your database allows SELECT ... FOR UPDATE with outer joins before using. #6764 [vitaly, Jeremy Kemper] * Add AssociationCollection#create! to be consistent with AssociationCollection#create when dealing with a foreign key that is a protected attribute [Cody Fauser] -* Added counter optimization for AssociationCollection#any? so person.friends.any? won't actually load the full association if we have the count in a cheaper form [DHH] +* Added counter optimization for AssociationCollection#any? so person.friends.any? won't actually load the full association if we have the count in a cheaper form [David Heinemeier Hansson] -* Change fixture_path to a class inheritable accessor allowing test cases to have their own custom set of fixtures. #6672 [zdennis] +* Change fixture_path to a class inheritable accessor allowing test cases to have their own custom set of fixtures. #6672 [Zach Dennis] * Quote ActiveSupport::Multibyte::Chars. #6653 [Julian Tarkhanov] @@ -881,15 +881,15 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Fix has_many :through to add the appropriate conditions when going through an association using STI. Closes #5783. [Jonathan Viney] -* fix select_limited_ids_list issues in postgresql, retain current behavior in other adapters [Rick] +* fix select_limited_ids_list issues in postgresql, retain current behavior in other adapters [Rick Olson] -* Restore eager condition interpolation, document it's differences [Rick] +* Restore eager condition interpolation, document it's differences [Rick Olson] * Don't rollback in teardown unless a transaction was started. Don't start a transaction in create_fixtures if a transaction is started. #6282 [Jacob Fugal, Jeremy Kemper] * Add #delete support to has_many :through associations. Closes #6049 [Martin Landers] -* Reverted old select_limited_ids_list postgresql fix that caused issues in mysql. Closes #5851 [Rick] +* Reverted old select_limited_ids_list postgresql fix that caused issues in mysql. Closes #5851 [Rick Olson] * Removes the ability for eager loaded conditions to be interpolated, since there is no model instance to use as a context for interpolation. #5553 [turnip@turnipspatch.com] @@ -897,7 +897,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Added update_attributes! which uses save! to raise an exception if a validation error prevents saving #6192 [jonathan] -* Deprecated add_on_boundary_breaking (use validates_length_of instead) #6292 [BobSilva] +* Deprecated add_on_boundary_breaking (use validates_length_of instead) #6292 [Bob Silva] * The has_many create method works with polymorphic associations. #6361 [Dan Peterson] @@ -913,9 +913,9 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * has_one associations with a nil target may be safely marshaled. #6279 [norbauer, Jeremy Kemper] -* Duplicate the hash provided to AR::Base#to_xml to prevent unexpected side effects [Koz] +* Duplicate the hash provided to AR::Base#to_xml to prevent unexpected side effects [Michael Koziarski] -* Add a :namespace option to AR::Base#to_xml [Koz] +* Add a :namespace option to AR::Base#to_xml [Michael Koziarski] * Deprecation tests. Remove warnings for dynamic finders and for the foo_count method if it's also an attribute. [Jeremy Kemper] @@ -923,7 +923,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Improve yaml fixtures error reporting. #6205 [Bruce Williams] -* Rename AR::Base#quote so people can use that name in their models. #3628 [Koz] +* Rename AR::Base#quote so people can use that name in their models. #3628 [Michael Koziarski] * Add deprecation warning for inferred foreign key. #6029 [Josh Susser] @@ -937,7 +937,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * to_xml: the :methods option works on arrays of records. #5845 [Josh Starcher] -* Deprecation: update docs. #5998 [jakob@mentalized.net, Kevin Clark] +* Deprecation: update docs. #5998 [Jakob Skjerning, Kevin Clark] * Add some XmlSerialization tests for ActiveRecord [Rick Olson] @@ -963,9 +963,9 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * MySQL: update test schema for MySQL 5 strict mode. #5861 [Tom Ward] -* to_xml: correct naming of included associations. #5831 [josh.starcher@gmail.com] +* to_xml: correct naming of included associations. #5831 [Josh Starcher] -* Pushing a record onto a has_many :through sets the association's foreign key to the associate's primary key and adds it to the correct association. #5815, #5829 [josh@hasmanythrough.com] +* Pushing a record onto a has_many :through sets the association's foreign key to the associate's primary key and adds it to the correct association. #5815, #5829 [Josh Susser] * Add records to has_many :through using <<, push, and concat by creating the association record. Raise if base or associate are new records since both ids are required to create the association. #build raises since you can't associate an unsaved record. #create! takes an attributes hash and creates the associated record and its association in a transaction. [Jeremy Kemper] @@ -981,7 +981,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Cache nil results for :included has_one associations also. #5787 [Michael Schoen] -* Fixed a bug which would cause .save to fail after trying to access a empty has_one association on a unsaved record. [Tobias Luetke] +* Fixed a bug which would cause .save to fail after trying to access a empty has_one association on a unsaved record. [Tobias Lütke] * Nested classes are given table names prefixed by the singular form of the parent's table name. [Jeremy Kemper] Example: Invoice::Lineitem is given table name invoice_lineitems @@ -1011,7 +1011,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Replace Reloadable with Reloadable::Deprecated. [Nicholas Seckar] -* Cache nil results for has_one associations so multiple calls don't call the database. Closes #5757. [Michael A. Schoen] +* Cache nil results for has_one associations so multiple calls don't call the database. Closes #5757. [Michael Schoen] * Add documentation for how to disable timestamps on a per model basis. Closes #5684. [matt@mattmargolis.net Marcel Molina Jr.] @@ -1019,9 +1019,9 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Refactor ActiveRecord::Base.reset_subclasses to #reset, and add global observer resetting. [Rick Olson] -* Formally deprecate the deprecated finders. [Koz] +* Formally deprecate the deprecated finders. [Michael Koziarski] -* Formally deprecate rich associations. [Koz] +* Formally deprecate rich associations. [Michael Koziarski] * Fixed that default timezones for new / initialize should uphold utc setting #5709 [daniluk@yahoo.com] @@ -1055,7 +1055,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * SQLServer: fix db:schema:dump case-sensitivity. #4684 [Will Rogers] -* Oracle: BigDecimal support. #5667 [schoenm@earthlink.net] +* Oracle: BigDecimal support. #5667 [Michael Schoen] * Numeric and decimal columns map to BigDecimal instead of Float. Those with scale 0 map to Integer. #5454 [robbat2@gentoo.org, work@ashleymoran.me.uk] @@ -1071,9 +1071,9 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Clearer has_one/belongs_to model names (account has_one :user). #5632 [matt@mattmargolis.net] -* Oracle: use nonblocking queries if allow_concurrency is set, fix pessimistic locking, don't guess date vs. time by default (set OracleAdapter.emulate_dates = true for the old behavior), adapter cleanup. #5635 [schoenm@earthlink.net] +* Oracle: use nonblocking queries if allow_concurrency is set, fix pessimistic locking, don't guess date vs. time by default (set OracleAdapter.emulate_dates = true for the old behavior), adapter cleanup. #5635 [Michael Schoen] -* Fixed a few Oracle issues: Allows Oracle's odd date handling to still work consistently within #to_xml, Passes test that hardcode insert statement by dropping the :id column, Updated RUNNING_UNIT_TESTS with Oracle instructions, Corrects method signature for #exec #5294 [schoenm@earthlink.net] +* Fixed a few Oracle issues: Allows Oracle's odd date handling to still work consistently within #to_xml, Passes test that hardcode insert statement by dropping the :id column, Updated RUNNING_UNIT_TESTS with Oracle instructions, Corrects method signature for #exec #5294 [Michael Schoen] * Added :group to available options for finds done on associations #5516 [mike@michaeldewey.org] @@ -1108,9 +1108,9 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Use explicit delegation instead of method aliasing for AR::Base.to_param -> AR::Base.id. #5299 (skaes@web.de) -* Refactored ActiveRecord::Base.to_xml to become a delegate for XmlSerializer, which restores sanity to the mega method. This refactoring also reinstates the opinions that type="string" is redundant and ugly and nil-differentiation is not a concern of serialization [DHH] +* Refactored ActiveRecord::Base.to_xml to become a delegate for XmlSerializer, which restores sanity to the mega method. This refactoring also reinstates the opinions that type="string" is redundant and ugly and nil-differentiation is not a concern of serialization [David Heinemeier Hansson] -* Added simple hash conditions to find that'll just convert hash to an AND-based condition string #5143 [hcatlin@gmail.com]. Example: +* Added simple hash conditions to find that'll just convert hash to an AND-based condition string #5143 [Hampton Catlin]. Example: Person.find(:all, :conditions => { :last_name => "Catlin", :status => 1 }, :limit => 2) @@ -1141,26 +1141,26 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] Foo.find(:all, :conditions => ['bar_id IN (?)', bars]) Foo.find(:first, :conditions => ['bar_id = ?', bar]) -* Fixed that Base.find :all, :conditions => [ "id IN (?)", collection ] would fail if collection was empty [DHH] +* Fixed that Base.find :all, :conditions => [ "id IN (?)", collection ] would fail if collection was empty [David Heinemeier Hansson] -* Add a list of regexes assert_queries skips in the ActiveRecord test suite. [Rick] +* Add a list of regexes assert_queries skips in the ActiveRecord test suite. [Rick Olson] -* Fix the has_and_belongs_to_many #create doesn't populate the join for new records. Closes #3692 [josh@hasmanythrough.com] +* Fix the has_and_belongs_to_many #create doesn't populate the join for new records. Closes #3692 [Josh Susser] * Provide Association Extensions access to the instance that the association is being accessed from. - Closes #4433 [josh@hasmanythrough.com] + Closes #4433 [Josh Susser] * Update OpenBase adaterp's maintainer's email address. Closes #5176. [Derrick Spell] -* Add a quick note about :select and eagerly included associations. [Rick] +* Add a quick note about :select and eagerly included associations. [Rick Olson] * Add docs for the :as option in has_one associations. Closes #5144 [cdcarter@gmail.com] -* Fixed that has_many collections shouldn't load the entire association to do build or create [DHH] +* Fixed that has_many collections shouldn't load the entire association to do build or create [David Heinemeier Hansson] -* Added :allow_nil option for aggregations #5091 [ian.w.white@gmail.com] +* Added :allow_nil option for aggregations #5091 [Ian White] -* Fix Oracle boolean support and tests. Closes #5139. [schoenm@earthlink.net] +* Fix Oracle boolean support and tests. Closes #5139. [Michael Schoen] * create! no longer blows up when no attributes are passed and a :create scope is in effect (e.g. foo.bars.create! failed whereas foo.bars.create!({}) didn't.) [Jeremy Kemper] @@ -1198,7 +1198,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Add warning about the proper way to validate the presence of a foreign key. Closes #4147. [Francois Beausoleil ] -* Fix syntax error in documentation. Closes #4679. [mislav@nippur.irb.hr] +* Fix syntax error in documentation. Closes #4679. [Mislav Marohnić] * Add Oracle support for CLOB inserts. Closes #4748. [schoenm@earthlink.net sandra.metz@duke.edu] @@ -1212,14 +1212,14 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Sybase Adapter type conversion cleanup. Closes #4736. [dev@metacasa.net] -* Fix bug where calculations with long alias names return null. [Rick] +* Fix bug where calculations with long alias names return null. [Rick Olson] -* Raise error when trying to add to a has_many :through association. Use the Join Model instead. [Rick] +* Raise error when trying to add to a has_many :through association. Use the Join Model instead. [Rick Olson] @post.tags << @tag # BAD @post.taggings.create(:tag => @tag) # GOOD -* Allow all calculations to take the :include option, not just COUNT (closes #4840) [Rick] +* Allow all calculations to take the :include option, not just COUNT (closes #4840) [Rick Olson] * Update inconsistent migrations documentation. #4683 [machomagna@gmail.com] @@ -1227,17 +1227,17 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Properly quote index names in migrations (closes #4764) [John Long] -* Fix the HasManyAssociation#count method so it uses the new ActiveRecord::Base#count syntax, while maintaining backwards compatibility. [Rick] +* Fix the HasManyAssociation#count method so it uses the new ActiveRecord::Base#count syntax, while maintaining backwards compatibility. [Rick Olson] -* Ensure that Associations#include_eager_conditions? checks both scoped and explicit conditions [Rick] +* Ensure that Associations#include_eager_conditions? checks both scoped and explicit conditions [Rick Olson] -* Associations#select_limited_ids_list adds the ORDER BY columns to the SELECT DISTINCT List for postgresql. [Rick] +* Associations#select_limited_ids_list adds the ORDER BY columns to the SELECT DISTINCT List for postgresql. [Rick Olson] * DRY up association collection reader method generation. [Marcel Molina Jr.] * DRY up and tweak style of the validation error object. [Marcel Molina Jr.] -* Add :case_sensitive option to validates_uniqueness_of (closes #3090) [Rick] +* Add :case_sensitive option to validates_uniqueness_of (closes #3090) [Rick Olson] class Account < ActiveRecord::Base validates_uniqueness_of :email, :case_sensitive => false @@ -1262,14 +1262,14 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] *1.15.2* (February 5th, 2007) -* Pass a range in :conditions to use the SQL BETWEEN operator. #6974 [dcmanges] +* Pass a range in :conditions to use the SQL BETWEEN operator. #6974 [Dan Manges] Student.find(:all, :conditions => { :grade => 9..12 }) -* Don't create instance writer methods for class attributes. [Rick] +* Don't create instance writer methods for class attributes. [Rick Olson] * When dealing with SQLite3, use the table_info pragma helper, so that the bindings can do some translation for when sqlite3 breaks incompatibly between point releases. [Jamis Buck] -* SQLServer: don't choke on strings containing 'null'. #7083 [Jakob S] +* SQLServer: don't choke on strings containing 'null'. #7083 [Jakob Skjerning] * Consistently use LOWER() for uniqueness validations (rather than mixing with UPPER()) so the database can always use a functional index on the lowercased column. #6495 [Si] @@ -1287,11 +1287,11 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] *1.15.0* (January 16th, 2007) -* [DOC] clear up some ambiguity with the way has_and_belongs_to_many creates the default join table name. #7072 [jeremymcanally] +* [DOC] clear up some ambiguity with the way has_and_belongs_to_many creates the default join table name. #7072 [Jeremy McAnally] -* change_column accepts :default => nil. Skip column options for primary keys. #6956, #7048 [dcmanges, Jeremy Kemper] +* change_column accepts :default => nil. Skip column options for primary keys. #6956, #7048 [Dan Manges, Jeremy Kemper] -* MySQL, PostgreSQL: change_column_default quotes the default value and doesn't lose column type information. #3987, #6664 [Jonathan Viney, manfred, altano@bigfoot.com] +* MySQL, PostgreSQL: change_column_default quotes the default value and doesn't lose column type information. #3987, #6664 [Jonathan Viney, Manfred Stienstra, altano@bigfoot.com] * Oracle: create_table takes a :sequence_name option to override the 'tablename_seq' default. #7000 [Michael Schoen] @@ -1352,15 +1352,15 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Fix has_many :through to add the appropriate conditions when going through an association using STI. Closes #5783. [Jonathan Viney] -* fix select_limited_ids_list issues in postgresql, retain current behavior in other adapters [Rick] +* fix select_limited_ids_list issues in postgresql, retain current behavior in other adapters [Rick Olson] -* Restore eager condition interpolation, document it's differences [Rick] +* Restore eager condition interpolation, document it's differences [Rick Olson] * Don't rollback in teardown unless a transaction was started. Don't start a transaction in create_fixtures if a transaction is started. #6282 [Jacob Fugal, Jeremy Kemper] * Add #delete support to has_many :through associations. Closes #6049 [Martin Landers] -* Reverted old select_limited_ids_list postgresql fix that caused issues in mysql. Closes #5851 [Rick] +* Reverted old select_limited_ids_list postgresql fix that caused issues in mysql. Closes #5851 [Rick Olson] * Removes the ability for eager loaded conditions to be interpolated, since there is no model instance to use as a context for interpolation. #5553 [turnip@turnipspatch.com] @@ -1368,7 +1368,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Added update_attributes! which uses save! to raise an exception if a validation error prevents saving #6192 [jonathan] -* Deprecated add_on_boundary_breaking (use validates_length_of instead) #6292 [BobSilva] +* Deprecated add_on_boundary_breaking (use validates_length_of instead) #6292 [Bob Silva] * The has_many create method works with polymorphic associations. #6361 [Dan Peterson] @@ -1384,9 +1384,9 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * has_one associations with a nil target may be safely marshaled. #6279 [norbauer, Jeremy Kemper] -* Duplicate the hash provided to AR::Base#to_xml to prevent unexpected side effects [Koz] +* Duplicate the hash provided to AR::Base#to_xml to prevent unexpected side effects [Michael Koziarski] -* Add a :namespace option to AR::Base#to_xml [Koz] +* Add a :namespace option to AR::Base#to_xml [Michael Koziarski] * Deprecation tests. Remove warnings for dynamic finders and for the foo_count method if it's also an attribute. [Jeremy Kemper] @@ -1394,7 +1394,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Improve yaml fixtures error reporting. #6205 [Bruce Williams] -* Rename AR::Base#quote so people can use that name in their models. #3628 [Koz] +* Rename AR::Base#quote so people can use that name in their models. #3628 [Michael Koziarski] * Add deprecation warning for inferred foreign key. #6029 [Josh Susser] @@ -1424,9 +1424,9 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * MySQL: update test schema for MySQL 5 strict mode. #5861 [Tom Ward] -* to_xml: correct naming of included associations. #5831 [josh.starcher@gmail.com] +* to_xml: correct naming of included associations. #5831 [Josh Starcher] -* Pushing a record onto a has_many :through sets the association's foreign key to the associate's primary key and adds it to the correct association. #5815, #5829 [josh@hasmanythrough.com] +* Pushing a record onto a has_many :through sets the association's foreign key to the associate's primary key and adds it to the correct association. #5815, #5829 [Josh Susser] * Add records to has_many :through using <<, push, and concat by creating the association record. Raise if base or associate are new records since both ids are required to create the association. #build raises since you can't associate an unsaved record. #create! takes an attributes hash and creates the associated record and its association in a transaction. [Jeremy Kemper] @@ -1442,7 +1442,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Cache nil results for :included has_one associations also. #5787 [Michael Schoen] -* Fixed a bug which would cause .save to fail after trying to access a empty has_one association on a unsaved record. [Tobias Luetke] +* Fixed a bug which would cause .save to fail after trying to access a empty has_one association on a unsaved record. [Tobias Lütke] * Nested classes are given table names prefixed by the singular form of the parent's table name. [Jeremy Kemper] Example: Invoice::Lineitem is given table name invoice_lineitems @@ -1470,15 +1470,15 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Replace Reloadable with Reloadable::Deprecated. [Nicholas Seckar] -* Cache nil results for has_one associations so multiple calls don't call the database. Closes #5757. [Michael A. Schoen] +* Cache nil results for has_one associations so multiple calls don't call the database. Closes #5757. [Michael Schoen] * Don't save has_one associations unnecessarily. #5735 [Jonathan Viney] * Refactor ActiveRecord::Base.reset_subclasses to #reset, and add global observer resetting. [Rick Olson] -* Formally deprecate the deprecated finders. [Koz] +* Formally deprecate the deprecated finders. [Michael Koziarski] -* Formally deprecate rich associations. [Koz] +* Formally deprecate rich associations. [Michael Koziarski] * Fixed that default timezones for new / initialize should uphold utc setting #5709 [daniluk@yahoo.com] @@ -1512,7 +1512,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * SQLServer: fix db:schema:dump case-sensitivity. #4684 [Will Rogers] -* Oracle: BigDecimal support. #5667 [schoenm@earthlink.net] +* Oracle: BigDecimal support. #5667 [Michael Schoen] * Numeric and decimal columns map to BigDecimal instead of Float. Those with scale 0 map to Integer. #5454 [robbat2@gentoo.org, work@ashleymoran.me.uk] @@ -1526,9 +1526,9 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Clearer has_one/belongs_to model names (account has_one :user). #5632 [matt@mattmargolis.net] -* Oracle: use nonblocking queries if allow_concurrency is set, fix pessimistic locking, don't guess date vs. time by default (set OracleAdapter.emulate_dates = true for the old behavior), adapter cleanup. #5635 [schoenm@earthlink.net] +* Oracle: use nonblocking queries if allow_concurrency is set, fix pessimistic locking, don't guess date vs. time by default (set OracleAdapter.emulate_dates = true for the old behavior), adapter cleanup. #5635 [Michael Schoen] -* Fixed a few Oracle issues: Allows Oracle's odd date handling to still work consistently within #to_xml, Passes test that hardcode insert statement by dropping the :id column, Updated RUNNING_UNIT_TESTS with Oracle instructions, Corrects method signature for #exec #5294 [schoenm@earthlink.net] +* Fixed a few Oracle issues: Allows Oracle's odd date handling to still work consistently within #to_xml, Passes test that hardcode insert statement by dropping the :id column, Updated RUNNING_UNIT_TESTS with Oracle instructions, Corrects method signature for #exec #5294 [Michael Schoen] * Added :group to available options for finds done on associations #5516 [mike@michaeldewey.org] @@ -1561,9 +1561,9 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Use explicit delegation instead of method aliasing for AR::Base.to_param -> AR::Base.id. #5299 (skaes@web.de) -* Refactored ActiveRecord::Base.to_xml to become a delegate for XmlSerializer, which restores sanity to the mega method. This refactoring also reinstates the opinions that type="string" is redundant and ugly and nil-differentiation is not a concern of serialization [DHH] +* Refactored ActiveRecord::Base.to_xml to become a delegate for XmlSerializer, which restores sanity to the mega method. This refactoring also reinstates the opinions that type="string" is redundant and ugly and nil-differentiation is not a concern of serialization [David Heinemeier Hansson] -* Added simple hash conditions to find that'll just convert hash to an AND-based condition string #5143 [hcatlin@gmail.com]. Example: +* Added simple hash conditions to find that'll just convert hash to an AND-based condition string #5143 [Hampton Catlin]. Example: Person.find(:all, :conditions => { :last_name => "Catlin", :status => 1 }, :limit => 2) @@ -1594,26 +1594,26 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] Foo.find(:all, :conditions => ['bar_id IN (?)', bars]) Foo.find(:first, :conditions => ['bar_id = ?', bar]) -* Fixed that Base.find :all, :conditions => [ "id IN (?)", collection ] would fail if collection was empty [DHH] +* Fixed that Base.find :all, :conditions => [ "id IN (?)", collection ] would fail if collection was empty [David Heinemeier Hansson] -* Add a list of regexes assert_queries skips in the ActiveRecord test suite. [Rick] +* Add a list of regexes assert_queries skips in the ActiveRecord test suite. [Rick Olson] -* Fix the has_and_belongs_to_many #create doesn't populate the join for new records. Closes #3692 [josh@hasmanythrough.com] +* Fix the has_and_belongs_to_many #create doesn't populate the join for new records. Closes #3692 [Josh Susser] * Provide Association Extensions access to the instance that the association is being accessed from. - Closes #4433 [josh@hasmanythrough.com] + Closes #4433 [Josh Susser] * Update OpenBase adaterp's maintainer's email address. Closes #5176. [Derrick Spell] -* Add a quick note about :select and eagerly included associations. [Rick] +* Add a quick note about :select and eagerly included associations. [Rick Olson] * Add docs for the :as option in has_one associations. Closes #5144 [cdcarter@gmail.com] -* Fixed that has_many collections shouldn't load the entire association to do build or create [DHH] +* Fixed that has_many collections shouldn't load the entire association to do build or create [David Heinemeier Hansson] -* Added :allow_nil option for aggregations #5091 [ian.w.white@gmail.com] +* Added :allow_nil option for aggregations #5091 [Ian White] -* Fix Oracle boolean support and tests. Closes #5139. [schoenm@earthlink.net] +* Fix Oracle boolean support and tests. Closes #5139. [Michael Schoen] * create! no longer blows up when no attributes are passed and a :create scope is in effect (e.g. foo.bars.create! failed whereas foo.bars.create!({}) didn't.) [Jeremy Kemper] @@ -1639,7 +1639,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Add warning about the proper way to validate the presence of a foreign key. Closes #4147. [Francois Beausoleil ] -* Fix syntax error in documentation. Closes #4679. [mislav@nippur.irb.hr] +* Fix syntax error in documentation. Closes #4679. [Mislav Marohnić] * Add Oracle support for CLOB inserts. Closes #4748. [schoenm@earthlink.net sandra.metz@duke.edu] @@ -1653,26 +1653,26 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Sybase Adapter type conversion cleanup. Closes #4736. [dev@metacasa.net] -* Fix bug where calculations with long alias names return null. [Rick] +* Fix bug where calculations with long alias names return null. [Rick Olson] -* Raise error when trying to add to a has_many :through association. Use the Join Model instead. [Rick] +* Raise error when trying to add to a has_many :through association. Use the Join Model instead. [Rick Olson] @post.tags << @tag # BAD @post.taggings.create(:tag => @tag) # GOOD -* Allow all calculations to take the :include option, not just COUNT (closes #4840) [Rick] +* Allow all calculations to take the :include option, not just COUNT (closes #4840) [Rick Olson] * Add ActiveRecord::Errors#to_xml [Jamis Buck] * Properly quote index names in migrations (closes #4764) [John Long] -* Fix the HasManyAssociation#count method so it uses the new ActiveRecord::Base#count syntax, while maintaining backwards compatibility. [Rick] +* Fix the HasManyAssociation#count method so it uses the new ActiveRecord::Base#count syntax, while maintaining backwards compatibility. [Rick Olson] -* Ensure that Associations#include_eager_conditions? checks both scoped and explicit conditions [Rick] +* Ensure that Associations#include_eager_conditions? checks both scoped and explicit conditions [Rick Olson] -* Associations#select_limited_ids_list adds the ORDER BY columns to the SELECT DISTINCT List for postgresql. [Rick] +* Associations#select_limited_ids_list adds the ORDER BY columns to the SELECT DISTINCT List for postgresql. [Rick Olson] -* Add :case_sensitive option to validates_uniqueness_of (closes #3090) [Rick] +* Add :case_sensitive option to validates_uniqueness_of (closes #3090) [Rick Olson] class Account < ActiveRecord::Base validates_uniqueness_of :email, :case_sensitive => false @@ -1689,7 +1689,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Add warning about the proper way to validate the presence of a foreign key. #4147 [Francois Beausoleil ] -* Fix syntax error in documentation. #4679 [mislav@nippur.irb.hr] +* Fix syntax error in documentation. #4679 [Mislav Marohnić] * Update inconsistent migrations documentation. #4683 [machomagna@gmail.com] @@ -1702,9 +1702,9 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Properly quote index names in migrations (closes #4764) [John Long] -* Ensure that Associations#include_eager_conditions? checks both scoped and explicit conditions [Rick] +* Ensure that Associations#include_eager_conditions? checks both scoped and explicit conditions [Rick Olson] -* Associations#select_limited_ids_list adds the ORDER BY columns to the SELECT DISTINCT List for postgresql. [Rick] +* Associations#select_limited_ids_list adds the ORDER BY columns to the SELECT DISTINCT List for postgresql. [Rick Olson] *1.14.2* (April 9th, 2006) @@ -1718,17 +1718,17 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Fixed that that multiparameter assignment doesn't work with aggregations (closes #4620) [Lars Pind] -* Enable Limit/Offset in Calculations (closes #4558) [lmarlow@yahoo.com] +* Enable Limit/Offset in Calculations (closes #4558) [lmarlow] -* Fixed that loading including associations returns all results if Load IDs For Limited Eager Loading returns none (closes #4528) [Rick] +* Fixed that loading including associations returns all results if Load IDs For Limited Eager Loading returns none (closes #4528) [Rick Olson] * Fixed HasManyAssociation#find bugs when :finder_sql is set #4600 [lagroue@free.fr] -* Allow AR::Base#respond_to? to behave when @attributes is nil [zenspider] +* Allow AR::Base#respond_to? to behave when @attributes is nil [Ryan Davis] -* Support eager includes when going through a polymorphic has_many association. [Rick] +* Support eager includes when going through a polymorphic has_many association. [Rick Olson] -* Added support for eagerly including polymorphic has_one associations. (closes #4525) [Rick] +* Added support for eagerly including polymorphic has_one associations. (closes #4525) [Rick Olson] class Post < ActiveRecord::Base has_one :tagging, :as => :taggable @@ -1736,9 +1736,9 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] Post.find :all, :include => :tagging -* Added descriptive error messages for invalid has_many :through associations: going through :has_one or :has_and_belongs_to_many [Rick] +* Added descriptive error messages for invalid has_many :through associations: going through :has_one or :has_and_belongs_to_many [Rick Olson] -* Added support for going through a polymorphic has_many association: (closes #4401) [Rick] +* Added support for going through a polymorphic has_many association: (closes #4401) [Rick Olson] class PhotoCollection < ActiveRecord::Base has_many :photos, :as => :photographic @@ -1756,36 +1756,36 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Changed those private ActiveRecord methods to take optional third argument :auto instead of nil for performance optimizations. (closes #4456) [Stefan] -* Private ActiveRecord methods add_limit!, add_joins!, and add_conditions! take an OPTIONAL third argument 'scope' (closes #4456) [Rick] +* Private ActiveRecord methods add_limit!, add_joins!, and add_conditions! take an OPTIONAL third argument 'scope' (closes #4456) [Rick Olson] -* DEPRECATED: Using additional attributes on has_and_belongs_to_many associations. Instead upgrade your association to be a real join model [DHH] +* DEPRECATED: Using additional attributes on has_and_belongs_to_many associations. Instead upgrade your association to be a real join model [David Heinemeier Hansson] -* Fixed that records returned from has_and_belongs_to_many associations with additional attributes should be marked as read only (fixes #4512) [DHH] +* Fixed that records returned from has_and_belongs_to_many associations with additional attributes should be marked as read only (fixes #4512) [David Heinemeier Hansson] * Do not implicitly mark recordss of has_many :through as readonly but do mark habtm records as readonly (eventually only on join tables without rich attributes). [Marcel Mollina Jr.] -* Fixed broken OCIAdapter #4457 [schoenm@earthlink.net] +* Fixed broken OCIAdapter #4457 [Michael Schoen] *1.14.0* (March 27th, 2006) * Replace 'rescue Object' with a finer grained rescue. Closes #4431. [Nicholas Seckar] -* Fixed eager loading so that an aliased table cannot clash with a has_and_belongs_to_many join table [Rick] +* Fixed eager loading so that an aliased table cannot clash with a has_and_belongs_to_many join table [Rick Olson] * Add support for :include to with_scope [andrew@redlinesoftware.com] -* Support the use of public synonyms with the Oracle adapter; required ruby-oci8 v0.1.14 #4390 [schoenm@earthlink.net] +* Support the use of public synonyms with the Oracle adapter; required ruby-oci8 v0.1.14 #4390 [Michael Schoen] * Change periods (.) in table aliases to _'s. Closes #4251 [jeff@ministrycentered.com] -* Changed has_and_belongs_to_many join to INNER JOIN for Mysql 3.23.x. Closes #4348 [Rick] +* Changed has_and_belongs_to_many join to INNER JOIN for Mysql 3.23.x. Closes #4348 [Rick Olson] -* Fixed issue that kept :select options from being scoped [Rick] +* Fixed issue that kept :select options from being scoped [Rick Olson] -* Fixed db_schema_import when binary types are present #3101 [DHH] +* Fixed db_schema_import when binary types are present #3101 [David Heinemeier Hansson] -* Fixed that MySQL enums should always be returned as strings #3501 [DHH] +* Fixed that MySQL enums should always be returned as strings #3501 [David Heinemeier Hansson] * Change has_many :through to use the :source option to specify the source association. :class_name is now ignored. [Rick Olson] @@ -1816,13 +1816,13 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] end end -* Fixed that schema changes while the database was open would break any connections to a SQLite database (now we reconnect if that error is throw) [DHH] +* Fixed that schema changes while the database was open would break any connections to a SQLite database (now we reconnect if that error is throw) [David Heinemeier Hansson] -* Don't classify the has_one class when eager loading, it is already singular. Add tests. (closes #4117) [jonathan@bluewire.net.nz] +* Don't classify the has_one class when eager loading, it is already singular. Add tests. (closes #4117) [Jonathan Viney] * Quit ignoring default :include options in has_many :through calls [Mark James] -* Allow has_many :through associations to find the source association by setting a custom class (closes #4307) [jonathan@bluewire.net.nz] +* Allow has_many :through associations to find the source association by setting a custom class (closes #4307) [Jonathan Viney] * Eager Loading support added for has_many :through => :has_many associations (see below). [Rick Olson] @@ -1842,13 +1842,13 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] belongs_to :client end -* Raise error when trying to select many polymorphic objects with has_many :through or :include (closes #4226) [josh@hasmanythrough.com] +* Raise error when trying to select many polymorphic objects with has_many :through or :include (closes #4226) [Josh Susser] -* Fixed has_many :through to include :conditions set on the :through association. closes #4020 [jonathan@bluewire.net.nz] +* Fixed has_many :through to include :conditions set on the :through association. closes #4020 [Jonathan Viney] -* Fix that has_many :through honors the foreign key set by the belongs_to association in the join model (closes #4259) [andylien@gmail.com / Rick] +* Fix that has_many :through honors the foreign key set by the belongs_to association in the join model (closes #4259) [andylien@gmail.com / Rick Olson] -* SQL Server adapter gets some love #4298 [rtomayko@gmail.com] +* SQL Server adapter gets some love #4298 [Ryan Tomayko] * Added OpenBase database adapter that builds on top of the http://www.spice-of-life.net/ruby-openbase/ driver. All functionality except LIMIT/OFFSET is supported #3528 [derrickspell@cdmplus.com] @@ -1856,27 +1856,27 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] Author.find(:all, :include => { :posts => :special_comments }, :order => 'special_comments.body') -* Add AbstractAdapter#table_alias_for to create table aliases according to the rules of the current adapter. [Rick] +* Add AbstractAdapter#table_alias_for to create table aliases according to the rules of the current adapter. [Rick Olson] -* Provide access to the underlying database connection through Adapter#raw_connection. Enables the use of db-specific methods without complicating the adapters. #2090 [Koz] +* Provide access to the underlying database connection through Adapter#raw_connection. Enables the use of db-specific methods without complicating the adapters. #2090 [Michael Koziarski] -* Remove broken attempts at handling columns with a default of 'now()' in the postgresql adapter. #2257 [Koz] +* Remove broken attempts at handling columns with a default of 'now()' in the postgresql adapter. #2257 [Michael Koziarski] -* Added connection#current_database that'll return of the current database (only works in MySQL, SQL Server, and Oracle so far -- please help implement for the rest of the adapters) #3663 [Tom ward] +* Added connection#current_database that'll return of the current database (only works in MySQL, SQL Server, and Oracle so far -- please help implement for the rest of the adapters) #3663 [Tom Ward] * Fixed that Migration#execute would have the table name prefix appended to its query #4110 [mark.imbriaco@pobox.com] * Make all tinyint(1) variants act like boolean in mysql (tinyint(1) unsigned, etc.) [Jamis Buck] -* Use association's :conditions when eager loading. [jeremyevans0@gmail.com] #4144 +* Use association's :conditions when eager loading. [Jeremy Evans] #4144 -* Alias the has_and_belongs_to_many join table on eager includes. #4106 [jeremyevans0@gmail.com] +* Alias the has_and_belongs_to_many join table on eager includes. #4106 [Jeremy Evans] This statement would normally error because the projects_developers table is joined twice, and therefore joined_on would be ambiguous. Developer.find(:all, :include => {:projects => :developers}, :conditions => 'join_project_developers.joined_on IS NOT NULL') -* Oracle adapter gets some love #4230 [schoenm@earthlink.net] +* Oracle adapter gets some love #4230 [Michael Schoen] * Changes :text to CLOB rather than BLOB [Moses Hohman] * Fixes an issue with nil numeric length/scales (several) @@ -1911,7 +1911,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] has_many :attachments, :as => :attachable, :dependent => :delete_all end -* Nicer error message on has_many :through when :through reflection can not be found. #4042 [court3nay@gmail.com] +* Nicer error message on has_many :through when :through reflection can not be found. #4042 [court3nay] * Upgrade to Transaction::Simple 1.3 [Jamis Buck] @@ -1923,7 +1923,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Dynamically set allow_concurrency. #4044 [Stefan Kaes] -* Added Base#to_xml that'll turn the current record into a XML representation [DHH]. Example: +* Added Base#to_xml that'll turn the current record into a XML representation [David Heinemeier Hansson]. Example: topic.to_xml @@ -2058,9 +2058,9 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * CHANGED DEFAULT: set ActiveRecord::Base.allow_concurrency to false. Most AR usage is in single-threaded applications. [Jeremy Kemper] -* Renamed the "oci" adapter to "oracle", but kept the old name as an alias #4017 [schoenm@earthlink.net] +* Renamed the "oci" adapter to "oracle", but kept the old name as an alias #4017 [Michael Schoen] -* Fixed that Base.save should always return false if the save didn't succeed, including if it has halted by before_save's #1861, #2477 [DHH] +* Fixed that Base.save should always return false if the save didn't succeed, including if it has halted by before_save's #1861, #2477 [David Heinemeier Hansson] * Speed up class -> connection caching and stale connection verification. #3979 [Stefan Kaes] @@ -2068,7 +2068,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Added that fixtures to placed in subdirectories of the main fixture files are also loaded #3937 [dblack@wobblini.net] -* Define attribute query methods to avoid method_missing calls. #3677 [jonathan@bluewire.net.nz] +* Define attribute query methods to avoid method_missing calls. #3677 [Jonathan Viney] * ActiveRecord::Base.remove_connection explicitly closes database connections and doesn't corrupt the connection cache. Introducing the disconnect! instance method for the PostgreSQL, MySQL, and SQL Server adapters; implementations for the others are welcome. #3591 [Simon Stapleton, Tom Ward] @@ -2092,7 +2092,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Fixed validates_length_of to work on UTF-8 strings by using characters instead of bytes #3699 [Masao Mutoh] -* Fixed that reflections would bleed across class boundaries in single-table inheritance setups #3796 [lars@pind.com] +* Fixed that reflections would bleed across class boundaries in single-table inheritance setups #3796 [Lars Pind] * Added calculations: Base.count, Base.average, Base.sum, Base.minimum, Base.maxmium, and the generic Base.calculate. All can be used with :group and :having. Calculations and statitics need no longer require custom SQL. #3958 [Rick Olson]. Examples: @@ -2101,7 +2101,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] Person.maximum :age Person.sum :salary, :group => :last_name -* Renamed Errors#count to Errors#size but kept an alias for the old name (and included an alias for length too) #3920 [contact@lukeredpath.co.uk] +* Renamed Errors#count to Errors#size but kept an alias for the old name (and included an alias for length too) #3920 [Luke Redpath] * Reflections don't attempt to resolve module nesting of association classes. Simplify type computation. [Jeremy Kemper] @@ -2109,7 +2109,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Fixed that the schema_info table used by ActiveRecord::Schema.define should respect table pre- and suffixes #3834 [rubyonrails@atyp.de] -* Added :select option to Base.count that'll allow you to select something else than * to be counted on. Especially important for count queries using DISTINCT #3839 [skaes] +* Added :select option to Base.count that'll allow you to select something else than * to be counted on. Especially important for count queries using DISTINCT #3839 [Stefan Kaes] * Correct syntax error in mysql DDL, and make AAACreateTablesTest run first [Bob Silva] @@ -2125,19 +2125,19 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Fix problems with count when used with :include [Jeremy Hopple and Kevin Clark] -* ActiveRecord::RecordInvalid now states which validations failed in its default error message [Tobias Luetke] +* ActiveRecord::RecordInvalid now states which validations failed in its default error message [Tobias Lütke] -* Using AssociationCollection#build with arrays of hashes should call build, not create [DHH] +* Using AssociationCollection#build with arrays of hashes should call build, not create [David Heinemeier Hansson] * Remove definition of reloadable? from ActiveRecord::Base to make way for new Reloadable code. [Nicholas Seckar] * Fixed schema handling for DB2 adapter that didn't work: an initial schema could be set, but it wasn't used when getting tables and indexes #3678 [Maik Schmidt] -* Support the :column option for remove_index with the PostgreSQL adapter. #3661 [shugo@ruby-lang.org] +* Support the :column option for remove_index with the PostgreSQL adapter. #3661 [Shugo Maeda] * Add documentation for add_index and remove_index. #3600 [Manfred Stienstra ] -* If the OCI library is not available, raise an exception indicating as much. #3593 [schoenm@earthlink.net] +* If the OCI library is not available, raise an exception indicating as much. #3593 [Michael Schoen] * Add explicit :order in finder tests as postgresql orders results differently by default. #3577. [Rick Olson] @@ -2145,7 +2145,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Show a meaningful error when the DB2 adapter cannot be loaded due to missing dependencies. [Nicholas Seckar] -* Make .count work for has_many associations with multi line finder sql [schoenm@earthlink.net] +* Make .count work for has_many associations with multi line finder sql [Michael Schoen] * Add AR::Base.base_class for querying the ancestor AR::Base subclass [Jamis Buck] @@ -2153,13 +2153,13 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Don't hardcode 'id' in acts as list. [ror@philippeapril.com] -* Fix date errors for SQLServer in association tests. #3406 [kevin.clark@gmal.com] +* Fix date errors for SQLServer in association tests. #3406 [Kevin Clark] * Escape database name in MySQL adapter when creating and dropping databases. #3409 [anna@wota.jp] * Disambiguate table names for columns in validates_uniquness_of's WHERE clause. #3423 [alex.borovsky@gmail.com] -* .with_scope imposed create parameters now bypass attr_protected [Tobias Luetke] +* .with_scope imposed create parameters now bypass attr_protected [Tobias Lütke] * Don't raise an exception when there are more keys than there are named bind variables when sanitizing conditions. [Marcel Molina Jr.] @@ -2167,25 +2167,25 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Sanitize scoped conditions. [Marcel Molina Jr.] -* Added option to Base.reflection_of_all_associations to specify a specific association to scope the call. For example Base.reflection_of_all_associations(:has_many) [DHH] +* Added option to Base.reflection_of_all_associations to specify a specific association to scope the call. For example Base.reflection_of_all_associations(:has_many) [David Heinemeier Hansson] -* Added ActiveRecord::SchemaDumper.ignore_tables which tells SchemaDumper which tables to ignore. Useful for tables with funky column like the ones required for tsearch2. [TobiasLuetke] +* Added ActiveRecord::SchemaDumper.ignore_tables which tells SchemaDumper which tables to ignore. Useful for tables with funky column like the ones required for tsearch2. [Tobias Lütke] -* SchemaDumper now doesn't fail anymore when there are unknown column types in the schema. Instead the table is ignored and a Comment is left in the schema.rb. [TobiasLuetke] +* SchemaDumper now doesn't fail anymore when there are unknown column types in the schema. Instead the table is ignored and a Comment is left in the schema.rb. [Tobias Lütke] * Fixed that saving a model with multiple habtm associations would only save the first one. #3244 [yanowitz-rubyonrails@quantumfoam.org, Florian Weber] * Fix change_column to work with PostgreSQL 7.x and 8.x. #3141 [wejn@box.cz, Rick Olson, Scott Barron] -* removed :piggyback in favor of just allowing :select on :through associations. [Tobias Luetke] +* removed :piggyback in favor of just allowing :select on :through associations. [Tobias Lütke] -* made method missing delegation to class methods on relation target work on :through associations. [Tobias Luetke] +* made method missing delegation to class methods on relation target work on :through associations. [Tobias Lütke] -* made .find() work on :through relations. [Tobias Luetke] +* made .find() work on :through relations. [Tobias Lütke] * Fix typo in association docs. #3296. [Blair Zajac] -* Fixed :through relations when using STI inherited classes would use the inherited class's name as foreign key on the join model [Tobias Luetke] +* Fixed :through relations when using STI inherited classes would use the inherited class's name as foreign key on the join model [Tobias Lütke] *1.13.2* (December 13th, 2005) @@ -2193,7 +2193,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * MySQL: allow encoding option for mysql.rb driver. [Jeremy Kemper] -* Added option inheritance for find calls on has_and_belongs_to_many and has_many assosociations [DHH]. Example: +* Added option inheritance for find calls on has_and_belongs_to_many and has_many assosociations [David Heinemeier Hansson]. Example: class Post has_many :recent_comments, :class_name => "Comment", :limit => 10, :include => :author @@ -2203,7 +2203,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] post.recent_comments.find(:all, :limit => nil) # Uses no limit but include authors post.recent_comments.find(:all, :limit => nil, :include => nil) # Uses no limit and doesn't include authors -* Added option to specify :group, :limit, :offset, and :select options from find on has_and_belongs_to_many and has_many assosociations [DHH] +* Added option to specify :group, :limit, :offset, and :select options from find on has_and_belongs_to_many and has_many assosociations [David Heinemeier Hansson] * MySQL: fixes for the bundled mysql.rb driver. #3160 [Justin Forder] @@ -2231,9 +2231,9 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * MySQL: work around ruby-mysql/mysql-ruby inconsistency with mysql.stat. Eliminate usage of mysql.ping because it doesn't guarantee reconnect. Explicitly close and reopen the connection instead. [Jeremy Kemper] -* Added preliminary support for polymorphic associations [DHH] +* Added preliminary support for polymorphic associations [David Heinemeier Hansson] -* Added preliminary support for join models [DHH] +* Added preliminary support for join models [David Heinemeier Hansson] * Allow validate_uniqueness_of to be scoped by more than just one column. #1559. [jeremy@jthopple.com, Marcel Molina Jr.] @@ -2259,7 +2259,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Add tasks to create, drop and rebuild the MySQL and PostgreSQL test databases. [Marcel Molina Jr.] -* Correct boolean handling in generated reader methods. #2945 [don.park@gmail.com, Stefan Kaes] +* Correct boolean handling in generated reader methods. #2945 [Don Park, Stefan Kaes] * Don't generate read methods for columns whose names are not valid ruby method names. #2946 [Stefan Kaes] @@ -2307,7 +2307,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Fix sqlite adaptor's detection of missing dbfile or database declaration. [Nicholas Seckar] -* Fixed acts_as_list for definitions without an explicit :order #2803 [jonathan@bluewire.net.nz] +* Fixed acts_as_list for definitions without an explicit :order #2803 [Jonathan Viney] * Upgrade bundled ruby-mysql 0.2.4 with mysql411 shim (see #440) to ruby-mysql 0.2.6 with a patchset for 4.1 protocol support. Local change [301] is now a part of the main driver; reapplied local change [2182]. Removed GC.start from Result.free. [tommy@tmtm.org, akuroda@gmail.com, Doug Fales , Jeremy Kemper] @@ -2326,7 +2326,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Fixed faulty regex in get_table_name method (SQLServerAdapter) #2639 [Ryan Tomayko] -* Added :include as an option for association declarations [DHH]. Example: +* Added :include as an option for association declarations [David Heinemeier Hansson]. Example: has_many :posts, :include => [ :author, :comments ] @@ -2341,7 +2341,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Fixed that SQL Server should ignore :size declarations on anything but integer and string in the agnostic schema representation #2756 [Ryan Tomayko] -* Added constrain scoping for creates using a hash of attributes bound to the :creation key [DHH]. Example: +* Added constrain scoping for creates using a hash of attributes bound to the :creation key [David Heinemeier Hansson]. Example: Comment.constrain(:creation => { :post_id => 5 }) do # Associated with :post_id @@ -2353,7 +2353,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] # If the tag doesn't exist, a new one is created that's associated with the person person.tags.find_or_create_by_name("Summer") -* Added find_or_create_by_X as a second type of dynamic finder that'll create the record if it doesn't already exist [DHH]. Example: +* Added find_or_create_by_X as a second type of dynamic finder that'll create the record if it doesn't already exist [David Heinemeier Hansson]. Example: # No 'Summer' tag exists Tag.find_or_create_by_name("Summer") # equal to Tag.create(:name => "Summer") @@ -2361,7 +2361,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] # Now the 'Summer' tag does exist Tag.find_or_create_by_name("Summer") # equal to Tag.find_by_name("Summer") -* Added extension capabilities to has_many and has_and_belongs_to_many proxies [DHH]. Example: +* Added extension capabilities to has_many and has_and_belongs_to_many proxies [David Heinemeier Hansson]. Example: class Account < ActiveRecord::Base has_many :people do @@ -2380,9 +2380,9 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] Note that the anoymous module must be declared using brackets, not do/end (due to order of evaluation). -* Omit internal dtproperties table from SQLServer table list. #2729 [rtomayko@gmail.com] +* Omit internal dtproperties table from SQLServer table list. #2729 [Ryan Tomayko] -* Quote column names in generated SQL. #2728 [rtomayko@gmail.com] +* Quote column names in generated SQL. #2728 [Ryan Tomayko] * Correct the pure-Ruby MySQL 4.1.1 shim's version test. #2718 [Jeremy Kemper] @@ -2396,7 +2396,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] * Worked around that connection can't be reset if allow_concurrency is off. #2648 [Michael Schoen ] -* Fixed SQL Server adapter to pass even more tests and do even better #2634 [rtomayko@gmail.com] +* Fixed SQL Server adapter to pass even more tests and do even better #2634 [Ryan Tomayko] * Fixed SQL Server adapter so it honors options[:conditions] when applying :limits #1978 [Tom Ward] @@ -2409,18 +2409,18 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Added :offset and :limit to the kinds of options that Base.constrain can use #2466 [duane.johnson@gmail.com] -* Fixed handling of nil number columns on Oracle and cleaned up tests for Oracle in general #2555 [schoenm@earthlink.net] +* Fixed handling of nil number columns on Oracle and cleaned up tests for Oracle in general #2555 [Michael Schoen] * Added quoted_true and quoted_false methods and tables to db2_adapter and cleaned up tests for DB2 #2493, #2624 [maik schmidt] *1.12.2* (October 26th, 2005) -* Allow symbols to rename columns when using SQLite adapter. #2531 [kevin.clark@gmail.com] +* Allow symbols to rename columns when using SQLite adapter. #2531 [Kevin Clark] * Map Active Record time to SQL TIME. #2575, #2576 [Robby Russell ] -* Clarify semantics of ActiveRecord::Base#respond_to? #2560 [skaes@web.de] +* Clarify semantics of ActiveRecord::Base#respond_to? #2560 [Stefan Kaes] * Fixed Association#clear for associations which have not yet been accessed. #2524 [Patrick Lenz ] @@ -2474,25 +2474,25 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Add test coverage for content_columns. #2432. [coffee2code] -* Speed up for unthreaded environments. #2431. [skaes@web.de] +* Speed up for unthreaded environments. #2431. [Stefan Kaes] -* Optimization for Mysql selects using mysql-ruby extension greater than 2.6.3. #2426. [skaes@web.de] +* Optimization for Mysql selects using mysql-ruby extension greater than 2.6.3. #2426. [Stefan Kaes] -* Speed up the setting of table_name. #2428. [skaes@web.de] +* Speed up the setting of table_name. #2428. [Stefan Kaes] -* Optimize instantiation of STI subclass records. In partial fullfilment of #1236. [skaes@web.de] +* Optimize instantiation of STI subclass records. In partial fullfilment of #1236. [Stefan Kaes] * Fix typo of 'constrains' to 'contraints'. #2069. [Michael Schuerig ] -* Optimization refactoring for add_limit_offset!. In partial fullfilment of #1236. [skaes@web.de] +* Optimization refactoring for add_limit_offset!. In partial fullfilment of #1236. [Stefan Kaes] * Add ability to get all siblings, including the current child, with acts_as_tree. Recloses #2140. [Michael Schuerig ] -* Add geometric type for postgresql adapter. #2233 [akaspick@gmail.com] +* Add geometric type for postgresql adapter. #2233 [Andrew Kaspick] -* Add option (true by default) to generate reader methods for each attribute of a record to avoid the overhead of calling method missing. In partial fullfilment of #1236. [skaes@web.de] +* Add option (true by default) to generate reader methods for each attribute of a record to avoid the overhead of calling method missing. In partial fullfilment of #1236. [Stefan Kaes] -* Add convenience predicate methods on Column class. In partial fullfilment of #1236. [skaes@web.de] +* Add convenience predicate methods on Column class. In partial fullfilment of #1236. [Stefan Kaes] * Raise errors when invalid hash keys are passed to ActiveRecord::Base.find. #2363 [Chad Fowler , Nicholas Seckar] @@ -2517,7 +2517,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Make update_attribute use the same writer method that update_attributes uses. #2237 [trevor@protocool.com] -* Make migrations honor table name prefixes and suffixes. #2298 [Jakob S, Marcel Molina] +* Make migrations honor table name prefixes and suffixes. #2298 [Jakob Skjerning, Marcel Molina Jr.] * Correct and optimize PostgreSQL bytea escaping. #1745, #1837 [dave@cherryville.org, ken@miriamtech.com, bellis@deepthought.org] @@ -2525,7 +2525,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Standardize the interpretation of boolean columns in the Mysql and Sqlite adapters. (Use MysqlAdapter.emulate_booleans = false to disable this behavior) -* Added new symbol-driven approach to activating observers with Base#observers= [DHH]. Example: +* Added new symbol-driven approach to activating observers with Base#observers= [David Heinemeier Hansson]. Example: ActiveRecord::Base.observers = :cacher, :garbage_collector @@ -2541,19 +2541,19 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Fixed that the create_x method from belongs_to wouldn't save the association properly #2042 [Florian Weber] -* Fixed saving a record with two unsaved belongs_to associations pointing to the same object #2023 [Tobias Luetke] +* Fixed saving a record with two unsaved belongs_to associations pointing to the same object #2023 [Tobias Lütke] * Improved migrations' behavior when the schema_info table is empty. [Nicholas Seckar] * Fixed that Observers didn't observe sub-classes #627 [Florian Weber] -* Fix eager loading error messages, allow :include to specify tables using strings or symbols. Closes #2222 [Marcel Molina] +* Fix eager loading error messages, allow :include to specify tables using strings or symbols. Closes #2222 [Marcel Molina Jr.] * Added check for RAILS_CONNECTION_ADAPTERS on startup and only load the connection adapters specified within if its present (available in Rails through config.connection_adapters using the new config) #1958 [skae] * Fixed various problems with has_and_belongs_to_many when using customer finder_sql #2094 [Florian Weber] -* Added better exception error when unknown column types are used with migrations #1814 [fbeausoleil@ftml.net] +* Added better exception error when unknown column types are used with migrations #1814 [François Beausoleil] * Fixed "connection lost" issue with the bundled Ruby/MySQL driver (would kill the app after 8 hours of inactivity) #2163, #428 [kajism@yahoo.com] @@ -2569,13 +2569,13 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Make sure the schema_info table is created before querying the current version #1903 -* Fixtures ignore table name prefix and suffix #1987 [Jakob S] +* Fixtures ignore table name prefix and suffix #1987 [Jakob Skjerning] -* Add documentation for index_type argument to add_index method for migrations #2005 [blaine@odeo.com] +* Add documentation for index_type argument to add_index method for migrations #2005 [Blaine] * Modify read_attribute to allow a symbol argument #2024 [Ken Kunz] -* Make destroy return self #1913 [sebastian.kanthak@muehlheim.de] +* Make destroy return self #1913 [Sebastian Kanthak] * Fix typo in validations documentation #1938 [court3nay] @@ -2597,7 +2597,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Fixed the handling of multiple blob columns in Oracle if one or more of them are null #1798 -* Added support for calling constrained class methods on has_many and has_and_belongs_to_many collections #1764 [Tobias Luetke] +* Added support for calling constrained class methods on has_many and has_and_belongs_to_many collections #1764 [Tobias Lütke] class Comment < AR:B def self.search(q) @@ -2629,19 +2629,19 @@ in effect. Added :readonly finder constraint. Calling an association collectio *1.11.1* (11 July, 2005) -* Added support for limit and offset with eager loading of has_one and belongs_to associations. Using the options with has_many and has_and_belongs_to_many associations will now raise an ActiveRecord::ConfigurationError #1692 [Rick Olsen] +* Added support for limit and offset with eager loading of has_one and belongs_to associations. Using the options with has_many and has_and_belongs_to_many associations will now raise an ActiveRecord::ConfigurationError #1692 [Rick Olson] * Fixed that assume_bottom_position (in acts_as_list) could be called on items already last in the list and they would move one position away from the list #1648 [tyler@kianta.com] * Added ActiveRecord::Base.threaded_connections flag to turn off 1-connection per thread (required for thread safety). By default it's on, but WEBrick in Rails need it off #1685 [Sam Stephenson] -* Correct reflected table name for singular associations. #1688 [court3nay@gmail.com] +* Correct reflected table name for singular associations. #1688 [court3nay] * Fixed optimistic locking with SQL Server #1660 [tom@popdog.net] * Added ActiveRecord::Migrator.migrate that can figure out whether to go up or down based on the target version and the current -* Added better error message for "packets out of order" #1630 [courtenay] +* Added better error message for "packets out of order" #1630 [court3nay] * Fixed first run of "rake migrate" on PostgreSQL by not expecting a return value on the id #1640 @@ -2652,7 +2652,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Changed logging of SQL statements to use the DEBUG level instead of INFO -* Added new Migrations framework for describing schema transformations in a way that can be easily applied across multiple databases #1604 [Tobias Luetke] See documentation under ActiveRecord::Migration and the additional support in the Rails rakefile/generator. +* Added new Migrations framework for describing schema transformations in a way that can be easily applied across multiple databases #1604 [Tobias Lütke] See documentation under ActiveRecord::Migration and the additional support in the Rails rakefile/generator. * Added callback hooks to association collections #1549 [Florian Weber]. Example: @@ -2675,13 +2675,13 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Speed up ActiveRecord#method_missing for the common case (read_attribute). -* Only notify observers on after_find and after_initialize if these methods are defined on the model. #1235 [skaes@web.de] +* Only notify observers on after_find and after_initialize if these methods are defined on the model. #1235 [Stefan Kaes] * Fixed that single-table inheritance sub-classes couldn't be used to limit the result set with eager loading #1215 [Chris McGrath] * Fixed validates_numericality_of to work with overrided getter-method when :allow_nil is on #1316 [raidel@onemail.at] -* Added roots, root, and siblings to the batch of methods added by acts_as_tree #1541 [michael@schuerig.de] +* Added roots, root, and siblings to the batch of methods added by acts_as_tree #1541 [Michael Schuerig] * Added support for limit/offset with the MS SQL Server driver so that pagination will now work #1569 [DeLynn Berry] @@ -2703,7 +2703,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio :conditions => 'project_id=1' ) -* Fixed that validations didn't respecting custom setting for too_short, too_long messages #1437 [Marcel Molina] +* Fixed that validations didn't respecting custom setting for too_short, too_long messages #1437 [Marcel Molina Jr.] * Fixed that clear_association_cache doesn't delete new associations on new records (so you can safely place new records in the session with Action Pack without having new associations wiped) #1494 [cluon] @@ -2730,7 +2730,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Corrected typo in find SQL for has_and_belongs_to_many. #1312 [ben@bensinclair.com] -* Fixed sanitized conditions for has_many finder method. #1281 [jackc@hylesanderson.com, pragdave, Tobias Luetke] +* Fixed sanitized conditions for has_many finder method. #1281 [jackc@hylesanderson.com, pragdave, Tobias Lütke] * Comprehensive PostgreSQL schema support. Use the optional schema_search_path directive in database.yml to give a comma-separated list of schemas to search for your tables. This allows you, for example, to have tables in a shared schema without having to use a custom table name. See http://www.postgresql.org/docs/8.0/interactive/ddl-schemas.html to learn more. #827 [dave@cherryville.org] @@ -2788,15 +2788,15 @@ in effect. Added :readonly finder constraint. Calling an association collectio # SELECT * FROM topics WHERE title IN ('First', 'Second') Topic.find_all_by_title(["First", "Second"]) -* Added compatibility with camelCase column names for dynamic finders #533 [Dee.Zsombor] +* Added compatibility with camelCase column names for dynamic finders #533 [Dee Zsombor] -* Fixed extraneous comma in count() function that made it not work with joins #1156 [jarkko/Dee.Zsombor] +* Fixed extraneous comma in count() function that made it not work with joins #1156 [Jarkko Laine/Dee Zsombor] * Fixed incompatibility with Base#find with an array of ids that would fail when using eager loading #1186 [Alisdair McDiarmid] * Fixed that validate_length_of lost :on option when :within was specified #1195 [jhosteny@mac.com] -* Added encoding and min_messages options for PostgreSQL #1205 [shugo]. Configuration example: +* Added encoding and min_messages options for PostgreSQL #1205 [Shugo Maeda]. Configuration example: development: adapter: postgresql @@ -2854,7 +2854,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio a single query. A good use case for this is a threaded post system, where you want to display every reply to a comment without multiple selects. -* Added Base.save! that attempts to save the record just like Base.save but will raise a RecordInvalid exception instead of returning false if the record is not valid [After much pestering from Dave Thomas] +* Added Base.save! that attempts to save the record just like Base.save but will raise a RecordInvalid exception instead of returning false if the record is not valid [Dave Thomas] * Fixed PostgreSQL usage of fixtures with regards to public schemas and table names with dots #962 [gnuman1@gmail.com] @@ -2884,7 +2884,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Fixed counter_sql when no records exist in database for PostgreSQL (would give error, not 0) #1039 [Caleb Tennis] -* Fixed that benchmarking times for rendering included db runtimes #987 [skaes@web.de] +* Fixed that benchmarking times for rendering included db runtimes #987 [Stefan Kaes] * Fixed boolean queries for t/f fields in PostgreSQL #995 [dave@cherryville.org] @@ -2892,9 +2892,9 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Fixed auto-stamping of dates (created_on/updated_on) for PostgreSQL #985 [dave@cherryville.org] -* Fixed Base.silence/benchmark to only log if a logger has been configured #986 [skaes@web.de] +* Fixed Base.silence/benchmark to only log if a logger has been configured #986 [Stefan Kaes] -* Added a join parameter as the third argument to Base.find_first and as the second to Base.count #426, #988 [skaes@web.de] +* Added a join parameter as the third argument to Base.find_first and as the second to Base.count #426, #988 [Stefan Kaes] * Fixed bug in Base#hash method that would treat records with the same string-based id as different [Dave Thomas] @@ -2980,7 +2980,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio account.save # => CC with id = 12 is destroyed -* Added validates_numericality_of #716 [skanthak/c.r.mcgrath]. Docuemntation: +* Added validates_numericality_of #716 [Sebastian Kanthak/Chris McGrath]. Docuemntation: Validates whether the value of the specified attribute is numeric by trying to convert it to a float with Kernel.Float (if integer is false) or applying it to the regular expression @@ -3050,7 +3050,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio 4. Added logic to the simplified_type method that allows the database to specify the scale of float data. 5. Adjusted the quote_column_name to account for the fact that MS SQL is bothered by a forward slash in the data string. -* Fixed that the dynamic finder like find_all_by_something_boolean(false) didn't work #649 [lmarlow@yahoo.com] +* Fixed that the dynamic finder like find_all_by_something_boolean(false) didn't work #649 [lmarlow] * Added validates_each that validates each specified attribute against a block #610 [Jeremy Kemper]. Example: @@ -3233,17 +3233,17 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Fixed that that multiparameter assignment doesn't work with aggregations (closes #4620) [Lars Pind] -* Enable Limit/Offset in Calculations (closes #4558) [lmarlow@yahoo.com] +* Enable Limit/Offset in Calculations (closes #4558) [lmarlow] -* Fixed that loading including associations returns all results if Load IDs For Limited Eager Loading returns none (closes #4528) [Rick] +* Fixed that loading including associations returns all results if Load IDs For Limited Eager Loading returns none (closes #4528) [Rick Olson] * Fixed HasManyAssociation#find bugs when :finder_sql is set #4600 [lagroue@free.fr] -* Allow AR::Base#respond_to? to behave when @attributes is nil [zenspider] +* Allow AR::Base#respond_to? to behave when @attributes is nil [Ryan Davis] -* Support eager includes when going through a polymorphic has_many association. [Rick] +* Support eager includes when going through a polymorphic has_many association. [Rick Olson] -* Added support for eagerly including polymorphic has_one associations. (closes #4525) [Rick] +* Added support for eagerly including polymorphic has_one associations. (closes #4525) [Rick Olson] class Post < ActiveRecord::Base has_one :tagging, :as => :taggable @@ -3251,9 +3251,9 @@ in effect. Added :readonly finder constraint. Calling an association collectio Post.find :all, :include => :tagging -* Added descriptive error messages for invalid has_many :through associations: going through :has_one or :has_and_belongs_to_many [Rick] +* Added descriptive error messages for invalid has_many :through associations: going through :has_one or :has_and_belongs_to_many [Rick Olson] -* Added support for going through a polymorphic has_many association: (closes #4401) [Rick] +* Added support for going through a polymorphic has_many association: (closes #4401) [Rick Olson] class PhotoCollection < ActiveRecord::Base has_many :photos, :as => :photographic @@ -3271,36 +3271,36 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Changed those private ActiveRecord methods to take optional third argument :auto instead of nil for performance optimizations. (closes #4456) [Stefan] -* Private ActiveRecord methods add_limit!, add_joins!, and add_conditions! take an OPTIONAL third argument 'scope' (closes #4456) [Rick] +* Private ActiveRecord methods add_limit!, add_joins!, and add_conditions! take an OPTIONAL third argument 'scope' (closes #4456) [Rick Olson] -* DEPRECATED: Using additional attributes on has_and_belongs_to_many associations. Instead upgrade your association to be a real join model [DHH] +* DEPRECATED: Using additional attributes on has_and_belongs_to_many associations. Instead upgrade your association to be a real join model [David Heinemeier Hansson] -* Fixed that records returned from has_and_belongs_to_many associations with additional attributes should be marked as read only (fixes #4512) [DHH] +* Fixed that records returned from has_and_belongs_to_many associations with additional attributes should be marked as read only (fixes #4512) [David Heinemeier Hansson] * Do not implicitly mark recordss of has_many :through as readonly but do mark habtm records as readonly (eventually only on join tables without rich attributes). [Marcel Mollina Jr.] -* Fixed broken OCIAdapter #4457 [schoenm@earthlink.net] +* Fixed broken OCIAdapter #4457 [Michael Schoen] *1.14.0* (March 27th, 2006) * Replace 'rescue Object' with a finer grained rescue. Closes #4431. [Nicholas Seckar] -* Fixed eager loading so that an aliased table cannot clash with a has_and_belongs_to_many join table [Rick] +* Fixed eager loading so that an aliased table cannot clash with a has_and_belongs_to_many join table [Rick Olson] * Add support for :include to with_scope [andrew@redlinesoftware.com] -* Support the use of public synonyms with the Oracle adapter; required ruby-oci8 v0.1.14 #4390 [schoenm@earthlink.net] +* Support the use of public synonyms with the Oracle adapter; required ruby-oci8 v0.1.14 #4390 [Michael Schoen] * Change periods (.) in table aliases to _'s. Closes #4251 [jeff@ministrycentered.com] -* Changed has_and_belongs_to_many join to INNER JOIN for Mysql 3.23.x. Closes #4348 [Rick] +* Changed has_and_belongs_to_many join to INNER JOIN for Mysql 3.23.x. Closes #4348 [Rick Olson] -* Fixed issue that kept :select options from being scoped [Rick] +* Fixed issue that kept :select options from being scoped [Rick Olson] -* Fixed db_schema_import when binary types are present #3101 [DHH] +* Fixed db_schema_import when binary types are present #3101 [David Heinemeier Hansson] -* Fixed that MySQL enums should always be returned as strings #3501 [DHH] +* Fixed that MySQL enums should always be returned as strings #3501 [David Heinemeier Hansson] * Change has_many :through to use the :source option to specify the source association. :class_name is now ignored. [Rick Olson] @@ -3331,13 +3331,13 @@ in effect. Added :readonly finder constraint. Calling an association collectio end end -* Fixed that schema changes while the database was open would break any connections to a SQLite database (now we reconnect if that error is throw) [DHH] +* Fixed that schema changes while the database was open would break any connections to a SQLite database (now we reconnect if that error is throw) [David Heinemeier Hansson] -* Don't classify the has_one class when eager loading, it is already singular. Add tests. (closes #4117) [jonathan@bluewire.net.nz] +* Don't classify the has_one class when eager loading, it is already singular. Add tests. (closes #4117) [Jonathan Viney] * Quit ignoring default :include options in has_many :through calls [Mark James] -* Allow has_many :through associations to find the source association by setting a custom class (closes #4307) [jonathan@bluewire.net.nz] +* Allow has_many :through associations to find the source association by setting a custom class (closes #4307) [Jonathan Viney] * Eager Loading support added for has_many :through => :has_many associations (see below). [Rick Olson] @@ -3357,13 +3357,13 @@ in effect. Added :readonly finder constraint. Calling an association collectio belongs_to :client end -* Raise error when trying to select many polymorphic objects with has_many :through or :include (closes #4226) [josh@hasmanythrough.com] +* Raise error when trying to select many polymorphic objects with has_many :through or :include (closes #4226) [Josh Susser] -* Fixed has_many :through to include :conditions set on the :through association. closes #4020 [jonathan@bluewire.net.nz] +* Fixed has_many :through to include :conditions set on the :through association. closes #4020 [Jonathan Viney] -* Fix that has_many :through honors the foreign key set by the belongs_to association in the join model (closes #4259) [andylien@gmail.com / Rick] +* Fix that has_many :through honors the foreign key set by the belongs_to association in the join model (closes #4259) [andylien@gmail.com / Rick Olson] -* SQL Server adapter gets some love #4298 [rtomayko@gmail.com] +* SQL Server adapter gets some love #4298 [Ryan Tomayko] * Added OpenBase database adapter that builds on top of the http://www.spice-of-life.net/ruby-openbase/ driver. All functionality except LIMIT/OFFSET is supported #3528 [derrickspell@cdmplus.com] @@ -3371,27 +3371,27 @@ in effect. Added :readonly finder constraint. Calling an association collectio Author.find(:all, :include => { :posts => :special_comments }, :order => 'special_comments.body') -* Add AbstractAdapter#table_alias_for to create table aliases according to the rules of the current adapter. [Rick] +* Add AbstractAdapter#table_alias_for to create table aliases according to the rules of the current adapter. [Rick Olson] -* Provide access to the underlying database connection through Adapter#raw_connection. Enables the use of db-specific methods without complicating the adapters. #2090 [Koz] +* Provide access to the underlying database connection through Adapter#raw_connection. Enables the use of db-specific methods without complicating the adapters. #2090 [Michael Koziarski] -* Remove broken attempts at handling columns with a default of 'now()' in the postgresql adapter. #2257 [Koz] +* Remove broken attempts at handling columns with a default of 'now()' in the postgresql adapter. #2257 [Michael Koziarski] -* Added connection#current_database that'll return of the current database (only works in MySQL, SQL Server, and Oracle so far -- please help implement for the rest of the adapters) #3663 [Tom ward] +* Added connection#current_database that'll return of the current database (only works in MySQL, SQL Server, and Oracle so far -- please help implement for the rest of the adapters) #3663 [Tom Ward] * Fixed that Migration#execute would have the table name prefix appended to its query #4110 [mark.imbriaco@pobox.com] * Make all tinyint(1) variants act like boolean in mysql (tinyint(1) unsigned, etc.) [Jamis Buck] -* Use association's :conditions when eager loading. [jeremyevans0@gmail.com] #4144 +* Use association's :conditions when eager loading. [Jeremy Evans] #4144 -* Alias the has_and_belongs_to_many join table on eager includes. #4106 [jeremyevans0@gmail.com] +* Alias the has_and_belongs_to_many join table on eager includes. #4106 [Jeremy Evans] This statement would normally error because the projects_developers table is joined twice, and therefore joined_on would be ambiguous. Developer.find(:all, :include => {:projects => :developers}, :conditions => 'join_project_developers.joined_on IS NOT NULL') -* Oracle adapter gets some love #4230 [schoenm@earthlink.net] +* Oracle adapter gets some love #4230 [Michael Schoen] * Changes :text to CLOB rather than BLOB [Moses Hohman] * Fixes an issue with nil numeric length/scales (several) @@ -3426,7 +3426,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio has_many :attachments, :as => :attachable, :dependent => :delete_all end -* Nicer error message on has_many :through when :through reflection can not be found. #4042 [court3nay@gmail.com] +* Nicer error message on has_many :through when :through reflection can not be found. #4042 [court3nay] * Upgrade to Transaction::Simple 1.3 [Jamis Buck] @@ -3438,7 +3438,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Dynamically set allow_concurrency. #4044 [Stefan Kaes] -* Added Base#to_xml that'll turn the current record into a XML representation [DHH]. Example: +* Added Base#to_xml that'll turn the current record into a XML representation [David Heinemeier Hansson]. Example: topic.to_xml @@ -3573,9 +3573,9 @@ in effect. Added :readonly finder constraint. Calling an association collectio * CHANGED DEFAULT: set ActiveRecord::Base.allow_concurrency to false. Most AR usage is in single-threaded applications. [Jeremy Kemper] -* Renamed the "oci" adapter to "oracle", but kept the old name as an alias #4017 [schoenm@earthlink.net] +* Renamed the "oci" adapter to "oracle", but kept the old name as an alias #4017 [Michael Schoen] -* Fixed that Base.save should always return false if the save didn't succeed, including if it has halted by before_save's #1861, #2477 [DHH] +* Fixed that Base.save should always return false if the save didn't succeed, including if it has halted by before_save's #1861, #2477 [David Heinemeier Hansson] * Speed up class -> connection caching and stale connection verification. #3979 [Stefan Kaes] @@ -3583,7 +3583,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Added that fixtures to placed in subdirectories of the main fixture files are also loaded #3937 [dblack@wobblini.net] -* Define attribute query methods to avoid method_missing calls. #3677 [jonathan@bluewire.net.nz] +* Define attribute query methods to avoid method_missing calls. #3677 [Jonathan Viney] * ActiveRecord::Base.remove_connection explicitly closes database connections and doesn't corrupt the connection cache. Introducing the disconnect! instance method for the PostgreSQL, MySQL, and SQL Server adapters; implementations for the others are welcome. #3591 [Simon Stapleton, Tom Ward] @@ -3607,7 +3607,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Fixed validates_length_of to work on UTF-8 strings by using characters instead of bytes #3699 [Masao Mutoh] -* Fixed that reflections would bleed across class boundaries in single-table inheritance setups #3796 [lars@pind.com] +* Fixed that reflections would bleed across class boundaries in single-table inheritance setups #3796 [Lars Pind] * Added calculations: Base.count, Base.average, Base.sum, Base.minimum, Base.maxmium, and the generic Base.calculate. All can be used with :group and :having. Calculations and statitics need no longer require custom SQL. #3958 [Rick Olson]. Examples: @@ -3616,7 +3616,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio Person.maximum :age Person.sum :salary, :group => :last_name -* Renamed Errors#count to Errors#size but kept an alias for the old name (and included an alias for length too) #3920 [contact@lukeredpath.co.uk] +* Renamed Errors#count to Errors#size but kept an alias for the old name (and included an alias for length too) #3920 [Luke Redpath] * Reflections don't attempt to resolve module nesting of association classes. Simplify type computation. [Jeremy Kemper] @@ -3624,7 +3624,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Fixed that the schema_info table used by ActiveRecord::Schema.define should respect table pre- and suffixes #3834 [rubyonrails@atyp.de] -* Added :select option to Base.count that'll allow you to select something else than * to be counted on. Especially important for count queries using DISTINCT #3839 [skaes] +* Added :select option to Base.count that'll allow you to select something else than * to be counted on. Especially important for count queries using DISTINCT #3839 [Stefan Kaes] * Correct syntax error in mysql DDL, and make AAACreateTablesTest run first [Bob Silva] @@ -3640,19 +3640,19 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Fix problems with count when used with :include [Jeremy Hopple and Kevin Clark] -* ActiveRecord::RecordInvalid now states which validations failed in its default error message [Tobias Luetke] +* ActiveRecord::RecordInvalid now states which validations failed in its default error message [Tobias Lütke] -* Using AssociationCollection#build with arrays of hashes should call build, not create [DHH] +* Using AssociationCollection#build with arrays of hashes should call build, not create [David Heinemeier Hansson] * Remove definition of reloadable? from ActiveRecord::Base to make way for new Reloadable code. [Nicholas Seckar] * Fixed schema handling for DB2 adapter that didn't work: an initial schema could be set, but it wasn't used when getting tables and indexes #3678 [Maik Schmidt] -* Support the :column option for remove_index with the PostgreSQL adapter. #3661 [shugo@ruby-lang.org] +* Support the :column option for remove_index with the PostgreSQL adapter. #3661 [Shugo Maeda] * Add documentation for add_index and remove_index. #3600 [Manfred Stienstra ] -* If the OCI library is not available, raise an exception indicating as much. #3593 [schoenm@earthlink.net] +* If the OCI library is not available, raise an exception indicating as much. #3593 [Michael Schoen] * Add explicit :order in finder tests as postgresql orders results differently by default. #3577. [Rick Olson] @@ -3660,7 +3660,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Show a meaningful error when the DB2 adapter cannot be loaded due to missing dependencies. [Nicholas Seckar] -* Make .count work for has_many associations with multi line finder sql [schoenm@earthlink.net] +* Make .count work for has_many associations with multi line finder sql [Michael Schoen] * Add AR::Base.base_class for querying the ancestor AR::Base subclass [Jamis Buck] @@ -3668,13 +3668,13 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Don't hardcode 'id' in acts as list. [ror@philippeapril.com] -* Fix date errors for SQLServer in association tests. #3406 [kevin.clark@gmal.com] +* Fix date errors for SQLServer in association tests. #3406 [Kevin Clark] * Escape database name in MySQL adapter when creating and dropping databases. #3409 [anna@wota.jp] * Disambiguate table names for columns in validates_uniquness_of's WHERE clause. #3423 [alex.borovsky@gmail.com] -* .with_scope imposed create parameters now bypass attr_protected [Tobias Luetke] +* .with_scope imposed create parameters now bypass attr_protected [Tobias Lütke] * Don't raise an exception when there are more keys than there are named bind variables when sanitizing conditions. [Marcel Molina Jr.] @@ -3682,25 +3682,25 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Sanitize scoped conditions. [Marcel Molina Jr.] -* Added option to Base.reflection_of_all_associations to specify a specific association to scope the call. For example Base.reflection_of_all_associations(:has_many) [DHH] +* Added option to Base.reflection_of_all_associations to specify a specific association to scope the call. For example Base.reflection_of_all_associations(:has_many) [David Heinemeier Hansson] -* Added ActiveRecord::SchemaDumper.ignore_tables which tells SchemaDumper which tables to ignore. Useful for tables with funky column like the ones required for tsearch2. [TobiasLuetke] +* Added ActiveRecord::SchemaDumper.ignore_tables which tells SchemaDumper which tables to ignore. Useful for tables with funky column like the ones required for tsearch2. [Tobias Lütke] -* SchemaDumper now doesn't fail anymore when there are unknown column types in the schema. Instead the table is ignored and a Comment is left in the schema.rb. [TobiasLuetke] +* SchemaDumper now doesn't fail anymore when there are unknown column types in the schema. Instead the table is ignored and a Comment is left in the schema.rb. [Tobias Lütke] * Fixed that saving a model with multiple habtm associations would only save the first one. #3244 [yanowitz-rubyonrails@quantumfoam.org, Florian Weber] * Fix change_column to work with PostgreSQL 7.x and 8.x. #3141 [wejn@box.cz, Rick Olson, Scott Barron] -* removed :piggyback in favor of just allowing :select on :through associations. [Tobias Luetke] +* removed :piggyback in favor of just allowing :select on :through associations. [Tobias Lütke] -* made method missing delegation to class methods on relation target work on :through associations. [Tobias Luetke] +* made method missing delegation to class methods on relation target work on :through associations. [Tobias Lütke] -* made .find() work on :through relations. [Tobias Luetke] +* made .find() work on :through relations. [Tobias Lütke] * Fix typo in association docs. #3296. [Blair Zajac] -* Fixed :through relations when using STI inherited classes would use the inherited class's name as foreign key on the join model [Tobias Luetke] +* Fixed :through relations when using STI inherited classes would use the inherited class's name as foreign key on the join model [Tobias Lütke] *1.13.2* (December 13th, 2005) @@ -3708,7 +3708,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * MySQL: allow encoding option for mysql.rb driver. [Jeremy Kemper] -* Added option inheritance for find calls on has_and_belongs_to_many and has_many assosociations [DHH]. Example: +* Added option inheritance for find calls on has_and_belongs_to_many and has_many assosociations [David Heinemeier Hansson]. Example: class Post has_many :recent_comments, :class_name => "Comment", :limit => 10, :include => :author @@ -3718,7 +3718,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio post.recent_comments.find(:all, :limit => nil) # Uses no limit but include authors post.recent_comments.find(:all, :limit => nil, :include => nil) # Uses no limit and doesn't include authors -* Added option to specify :group, :limit, :offset, and :select options from find on has_and_belongs_to_many and has_many assosociations [DHH] +* Added option to specify :group, :limit, :offset, and :select options from find on has_and_belongs_to_many and has_many assosociations [David Heinemeier Hansson] * MySQL: fixes for the bundled mysql.rb driver. #3160 [Justin Forder] @@ -3736,7 +3736,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * MySQL: more robust test for nullified result hashes. #3124 [Stefan Kaes] -* Reloading an instance refreshes its aggregations as well as its associations. #3024 [François Beausolei] +* Reloading an instance refreshes its aggregations as well as its associations. #3024 [François Beausoleil] * Fixed that using :include together with :conditions array in Base.find would cause NoMethodError #2887 [Paul Hammmond] @@ -3746,9 +3746,9 @@ in effect. Added :readonly finder constraint. Calling an association collectio * MySQL: work around ruby-mysql/mysql-ruby inconsistency with mysql.stat. Eliminate usage of mysql.ping because it doesn't guarantee reconnect. Explicitly close and reopen the connection instead. [Jeremy Kemper] -* Added preliminary support for polymorphic associations [DHH] +* Added preliminary support for polymorphic associations [David Heinemeier Hansson] -* Added preliminary support for join models [DHH] +* Added preliminary support for join models [David Heinemeier Hansson] * Allow validate_uniqueness_of to be scoped by more than just one column. #1559. [jeremy@jthopple.com, Marcel Molina Jr.] @@ -3774,7 +3774,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Add tasks to create, drop and rebuild the MySQL and PostgreSQL test databases. [Marcel Molina Jr.] -* Correct boolean handling in generated reader methods. #2945 [don.park@gmail.com, Stefan Kaes] +* Correct boolean handling in generated reader methods. #2945 [Don Park, Stefan Kaes] * Don't generate read methods for columns whose names are not valid ruby method names. #2946 [Stefan Kaes] @@ -3822,7 +3822,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Fix sqlite adaptor's detection of missing dbfile or database declaration. [Nicholas Seckar] -* Fixed acts_as_list for definitions without an explicit :order #2803 [jonathan@bluewire.net.nz] +* Fixed acts_as_list for definitions without an explicit :order #2803 [Jonathan Viney] * Upgrade bundled ruby-mysql 0.2.4 with mysql411 shim (see #440) to ruby-mysql 0.2.6 with a patchset for 4.1 protocol support. Local change [301] is now a part of the main driver; reapplied local change [2182]. Removed GC.start from Result.free. [tommy@tmtm.org, akuroda@gmail.com, Doug Fales , Jeremy Kemper] @@ -3841,7 +3841,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Fixed faulty regex in get_table_name method (SQLServerAdapter) #2639 [Ryan Tomayko] -* Added :include as an option for association declarations [DHH]. Example: +* Added :include as an option for association declarations [David Heinemeier Hansson]. Example: has_many :posts, :include => [ :author, :comments ] @@ -3856,7 +3856,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Fixed that SQL Server should ignore :size declarations on anything but integer and string in the agnostic schema representation #2756 [Ryan Tomayko] -* Added constrain scoping for creates using a hash of attributes bound to the :creation key [DHH]. Example: +* Added constrain scoping for creates using a hash of attributes bound to the :creation key [David Heinemeier Hansson]. Example: Comment.constrain(:creation => { :post_id => 5 }) do # Associated with :post_id @@ -3868,7 +3868,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio # If the tag doesn't exist, a new one is created that's associated with the person person.tags.find_or_create_by_name("Summer") -* Added find_or_create_by_X as a second type of dynamic finder that'll create the record if it doesn't already exist [DHH]. Example: +* Added find_or_create_by_X as a second type of dynamic finder that'll create the record if it doesn't already exist [David Heinemeier Hansson]. Example: # No 'Summer' tag exists Tag.find_or_create_by_name("Summer") # equal to Tag.create(:name => "Summer") @@ -3876,7 +3876,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio # Now the 'Summer' tag does exist Tag.find_or_create_by_name("Summer") # equal to Tag.find_by_name("Summer") -* Added extension capabilities to has_many and has_and_belongs_to_many proxies [DHH]. Example: +* Added extension capabilities to has_many and has_and_belongs_to_many proxies [David Heinemeier Hansson]. Example: class Account < ActiveRecord::Base has_many :people do @@ -3895,9 +3895,9 @@ in effect. Added :readonly finder constraint. Calling an association collectio Note that the anoymous module must be declared using brackets, not do/end (due to order of evaluation). -* Omit internal dtproperties table from SQLServer table list. #2729 [rtomayko@gmail.com] +* Omit internal dtproperties table from SQLServer table list. #2729 [Ryan Tomayko] -* Quote column names in generated SQL. #2728 [rtomayko@gmail.com] +* Quote column names in generated SQL. #2728 [Ryan Tomayko] * Correct the pure-Ruby MySQL 4.1.1 shim's version test. #2718 [Jeremy Kemper] @@ -3911,7 +3911,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Worked around that connection can't be reset if allow_concurrency is off. #2648 [Michael Schoen ] -* Fixed SQL Server adapter to pass even more tests and do even better #2634 [rtomayko@gmail.com] +* Fixed SQL Server adapter to pass even more tests and do even better #2634 [Ryan Tomayko] * Fixed SQL Server adapter so it honors options[:conditions] when applying :limits #1978 [Tom Ward] @@ -3924,18 +3924,18 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Added :offset and :limit to the kinds of options that Base.constrain can use #2466 [duane.johnson@gmail.com] -* Fixed handling of nil number columns on Oracle and cleaned up tests for Oracle in general #2555 [schoenm@earthlink.net] +* Fixed handling of nil number columns on Oracle and cleaned up tests for Oracle in general #2555 [Michael Schoen] * Added quoted_true and quoted_false methods and tables to db2_adapter and cleaned up tests for DB2 #2493, #2624 [maik schmidt] *1.12.2* (October 26th, 2005) -* Allow symbols to rename columns when using SQLite adapter. #2531 [kevin.clark@gmail.com] +* Allow symbols to rename columns when using SQLite adapter. #2531 [Kevin Clark] * Map Active Record time to SQL TIME. #2575, #2576 [Robby Russell ] -* Clarify semantics of ActiveRecord::Base#respond_to? #2560 [skaes@web.de] +* Clarify semantics of ActiveRecord::Base#respond_to? #2560 [Stefan Kaes] * Fixed Association#clear for associations which have not yet been accessed. #2524 [Patrick Lenz ] @@ -3989,25 +3989,25 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Add test coverage for content_columns. #2432. [coffee2code] -* Speed up for unthreaded environments. #2431. [skaes@web.de] +* Speed up for unthreaded environments. #2431. [Stefan Kaes] -* Optimization for Mysql selects using mysql-ruby extension greater than 2.6.3. #2426. [skaes@web.de] +* Optimization for Mysql selects using mysql-ruby extension greater than 2.6.3. #2426. [Stefan Kaes] -* Speed up the setting of table_name. #2428. [skaes@web.de] +* Speed up the setting of table_name. #2428. [Stefan Kaes] -* Optimize instantiation of STI subclass records. In partial fullfilment of #1236. [skaes@web.de] +* Optimize instantiation of STI subclass records. In partial fullfilment of #1236. [Stefan Kaes] * Fix typo of 'constrains' to 'contraints'. #2069. [Michael Schuerig ] -* Optimization refactoring for add_limit_offset!. In partial fullfilment of #1236. [skaes@web.de] +* Optimization refactoring for add_limit_offset!. In partial fullfilment of #1236. [Stefan Kaes] * Add ability to get all siblings, including the current child, with acts_as_tree. Recloses #2140. [Michael Schuerig ] -* Add geometric type for postgresql adapter. #2233 [akaspick@gmail.com] +* Add geometric type for postgresql adapter. #2233 [Andrew Kaspick] -* Add option (true by default) to generate reader methods for each attribute of a record to avoid the overhead of calling method missing. In partial fullfilment of #1236. [skaes@web.de] +* Add option (true by default) to generate reader methods for each attribute of a record to avoid the overhead of calling method missing. In partial fullfilment of #1236. [Stefan Kaes] -* Add convenience predicate methods on Column class. In partial fullfilment of #1236. [skaes@web.de] +* Add convenience predicate methods on Column class. In partial fullfilment of #1236. [Stefan Kaes] * Raise errors when invalid hash keys are passed to ActiveRecord::Base.find. #2363 [Chad Fowler , Nicholas Seckar] @@ -4032,7 +4032,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Make update_attribute use the same writer method that update_attributes uses. #2237 [trevor@protocool.com] -* Make migrations honor table name prefixes and suffixes. #2298 [Jakob S, Marcel Molina] +* Make migrations honor table name prefixes and suffixes. #2298 [Jakob Skjerning, Marcel Molina Jr.] * Correct and optimize PostgreSQL bytea escaping. #1745, #1837 [dave@cherryville.org, ken@miriamtech.com, bellis@deepthought.org] @@ -4040,7 +4040,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Standardize the interpretation of boolean columns in the Mysql and Sqlite adapters. (Use MysqlAdapter.emulate_booleans = false to disable this behavior) -* Added new symbol-driven approach to activating observers with Base#observers= [DHH]. Example: +* Added new symbol-driven approach to activating observers with Base#observers= [David Heinemeier Hansson]. Example: ActiveRecord::Base.observers = :cacher, :garbage_collector @@ -4056,19 +4056,19 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Fixed that the create_x method from belongs_to wouldn't save the association properly #2042 [Florian Weber] -* Fixed saving a record with two unsaved belongs_to associations pointing to the same object #2023 [Tobias Luetke] +* Fixed saving a record with two unsaved belongs_to associations pointing to the same object #2023 [Tobias Lütke] * Improved migrations' behavior when the schema_info table is empty. [Nicholas Seckar] * Fixed that Observers didn't observe sub-classes #627 [Florian Weber] -* Fix eager loading error messages, allow :include to specify tables using strings or symbols. Closes #2222 [Marcel Molina] +* Fix eager loading error messages, allow :include to specify tables using strings or symbols. Closes #2222 [Marcel Molina Jr.] * Added check for RAILS_CONNECTION_ADAPTERS on startup and only load the connection adapters specified within if its present (available in Rails through config.connection_adapters using the new config) #1958 [skae] * Fixed various problems with has_and_belongs_to_many when using customer finder_sql #2094 [Florian Weber] -* Added better exception error when unknown column types are used with migrations #1814 [fbeausoleil@ftml.net] +* Added better exception error when unknown column types are used with migrations #1814 [François Beausoleil] * Fixed "connection lost" issue with the bundled Ruby/MySQL driver (would kill the app after 8 hours of inactivity) #2163, #428 [kajism@yahoo.com] @@ -4084,13 +4084,13 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Make sure the schema_info table is created before querying the current version #1903 -* Fixtures ignore table name prefix and suffix #1987 [Jakob S] +* Fixtures ignore table name prefix and suffix #1987 [Jakob Skjerning] -* Add documentation for index_type argument to add_index method for migrations #2005 [blaine@odeo.com] +* Add documentation for index_type argument to add_index method for migrations #2005 [Blaine] * Modify read_attribute to allow a symbol argument #2024 [Ken Kunz] -* Make destroy return self #1913 [sebastian.kanthak@muehlheim.de] +* Make destroy return self #1913 [Sebastian Kanthak] * Fix typo in validations documentation #1938 [court3nay] @@ -4112,7 +4112,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Fixed the handling of multiple blob columns in Oracle if one or more of them are null #1798 -* Added support for calling constrained class methods on has_many and has_and_belongs_to_many collections #1764 [Tobias Luetke] +* Added support for calling constrained class methods on has_many and has_and_belongs_to_many collections #1764 [Tobias Lütke] class Comment < AR:B def self.search(q) @@ -4144,19 +4144,19 @@ in effect. Added :readonly finder constraint. Calling an association collectio *1.11.1* (11 July, 2005) -* Added support for limit and offset with eager loading of has_one and belongs_to associations. Using the options with has_many and has_and_belongs_to_many associations will now raise an ActiveRecord::ConfigurationError #1692 [Rick Olsen] +* Added support for limit and offset with eager loading of has_one and belongs_to associations. Using the options with has_many and has_and_belongs_to_many associations will now raise an ActiveRecord::ConfigurationError #1692 [Rick Olson] * Fixed that assume_bottom_position (in acts_as_list) could be called on items already last in the list and they would move one position away from the list #1648 [tyler@kianta.com] * Added ActiveRecord::Base.threaded_connections flag to turn off 1-connection per thread (required for thread safety). By default it's on, but WEBrick in Rails need it off #1685 [Sam Stephenson] -* Correct reflected table name for singular associations. #1688 [court3nay@gmail.com] +* Correct reflected table name for singular associations. #1688 [court3nay] * Fixed optimistic locking with SQL Server #1660 [tom@popdog.net] * Added ActiveRecord::Migrator.migrate that can figure out whether to go up or down based on the target version and the current -* Added better error message for "packets out of order" #1630 [courtenay] +* Added better error message for "packets out of order" #1630 [court3nay] * Fixed first run of "rake migrate" on PostgreSQL by not expecting a return value on the id #1640 @@ -4167,7 +4167,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Changed logging of SQL statements to use the DEBUG level instead of INFO -* Added new Migrations framework for describing schema transformations in a way that can be easily applied across multiple databases #1604 [Tobias Luetke] See documentation under ActiveRecord::Migration and the additional support in the Rails rakefile/generator. +* Added new Migrations framework for describing schema transformations in a way that can be easily applied across multiple databases #1604 [Tobias Lütke] See documentation under ActiveRecord::Migration and the additional support in the Rails rakefile/generator. * Added callback hooks to association collections #1549 [Florian Weber]. Example: @@ -4190,13 +4190,13 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Speed up ActiveRecord#method_missing for the common case (read_attribute). -* Only notify observers on after_find and after_initialize if these methods are defined on the model. #1235 [skaes@web.de] +* Only notify observers on after_find and after_initialize if these methods are defined on the model. #1235 [Stefan Kaes] * Fixed that single-table inheritance sub-classes couldn't be used to limit the result set with eager loading #1215 [Chris McGrath] * Fixed validates_numericality_of to work with overrided getter-method when :allow_nil is on #1316 [raidel@onemail.at] -* Added roots, root, and siblings to the batch of methods added by acts_as_tree #1541 [michael@schuerig.de] +* Added roots, root, and siblings to the batch of methods added by acts_as_tree #1541 [Michael Schuerig] * Added support for limit/offset with the MS SQL Server driver so that pagination will now work #1569 [DeLynn Berry] @@ -4218,7 +4218,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio :conditions => 'project_id=1' ) -* Fixed that validations didn't respecting custom setting for too_short, too_long messages #1437 [Marcel Molina] +* Fixed that validations didn't respecting custom setting for too_short, too_long messages #1437 [Marcel Molina Jr.] * Fixed that clear_association_cache doesn't delete new associations on new records (so you can safely place new records in the session with Action Pack without having new associations wiped) #1494 [cluon] @@ -4245,7 +4245,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Corrected typo in find SQL for has_and_belongs_to_many. #1312 [ben@bensinclair.com] -* Fixed sanitized conditions for has_many finder method. #1281 [jackc@hylesanderson.com, pragdave, Tobias Luetke] +* Fixed sanitized conditions for has_many finder method. #1281 [jackc@hylesanderson.com, pragdave, Tobias Lütke] * Comprehensive PostgreSQL schema support. Use the optional schema_search_path directive in database.yml to give a comma-separated list of schemas to search for your tables. This allows you, for example, to have tables in a shared schema without having to use a custom table name. See http://www.postgresql.org/docs/8.0/interactive/ddl-schemas.html to learn more. #827 [dave@cherryville.org] @@ -4303,15 +4303,15 @@ in effect. Added :readonly finder constraint. Calling an association collectio # SELECT * FROM topics WHERE title IN ('First', 'Second') Topic.find_all_by_title(["First", "Second"]) -* Added compatibility with camelCase column names for dynamic finders #533 [Dee.Zsombor] +* Added compatibility with camelCase column names for dynamic finders #533 [Dee Zsombor] -* Fixed extraneous comma in count() function that made it not work with joins #1156 [jarkko/Dee.Zsombor] +* Fixed extraneous comma in count() function that made it not work with joins #1156 [Jarkko Laine/Dee Zsombor] * Fixed incompatibility with Base#find with an array of ids that would fail when using eager loading #1186 [Alisdair McDiarmid] * Fixed that validate_length_of lost :on option when :within was specified #1195 [jhosteny@mac.com] -* Added encoding and min_messages options for PostgreSQL #1205 [shugo]. Configuration example: +* Added encoding and min_messages options for PostgreSQL #1205 [Shugo Maeda]. Configuration example: development: adapter: postgresql @@ -4369,7 +4369,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio a single query. A good use case for this is a threaded post system, where you want to display every reply to a comment without multiple selects. -* Added Base.save! that attempts to save the record just like Base.save but will raise a RecordInvalid exception instead of returning false if the record is not valid [After much pestering from Dave Thomas] +* Added Base.save! that attempts to save the record just like Base.save but will raise a RecordInvalid exception instead of returning false if the record is not valid [Dave Thomas] * Fixed PostgreSQL usage of fixtures with regards to public schemas and table names with dots #962 [gnuman1@gmail.com] @@ -4399,7 +4399,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Fixed counter_sql when no records exist in database for PostgreSQL (would give error, not 0) #1039 [Caleb Tennis] -* Fixed that benchmarking times for rendering included db runtimes #987 [skaes@web.de] +* Fixed that benchmarking times for rendering included db runtimes #987 [Stefan Kaes] * Fixed boolean queries for t/f fields in PostgreSQL #995 [dave@cherryville.org] @@ -4407,9 +4407,9 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Fixed auto-stamping of dates (created_on/updated_on) for PostgreSQL #985 [dave@cherryville.org] -* Fixed Base.silence/benchmark to only log if a logger has been configured #986 [skaes@web.de] +* Fixed Base.silence/benchmark to only log if a logger has been configured #986 [Stefan Kaes] -* Added a join parameter as the third argument to Base.find_first and as the second to Base.count #426, #988 [skaes@web.de] +* Added a join parameter as the third argument to Base.find_first and as the second to Base.count #426, #988 [Stefan Kaes] * Fixed bug in Base#hash method that would treat records with the same string-based id as different [Dave Thomas] @@ -4495,7 +4495,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio account.save # => CC with id = 12 is destroyed -* Added validates_numericality_of #716 [skanthak/c.r.mcgrath]. Docuemntation: +* Added validates_numericality_of #716 [Sebastian Kanthak/Chris McGrath]. Docuemntation: Validates whether the value of the specified attribute is numeric by trying to convert it to a float with Kernel.Float (if integer is false) or applying it to the regular expression @@ -4565,7 +4565,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio 4. Added logic to the simplified_type method that allows the database to specify the scale of float data. 5. Adjusted the quote_column_name to account for the fact that MS SQL is bothered by a forward slash in the data string. -* Fixed that the dynamic finder like find_all_by_something_boolean(false) didn't work #649 [lmarlow@yahoo.com] +* Fixed that the dynamic finder like find_all_by_something_boolean(false) didn't work #649 [lmarlow] * Added validates_each that validates each specified attribute against a block #610 [Jeremy Kemper]. Example: @@ -4777,7 +4777,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio After: before_destroy { |record| Person.destroy_all "firm_id = #{record.id}" } -* Added :counter_cache option to acts_as_tree that works just like the one you can define on belongs_to #371 [Josh] +* Added :counter_cache option to acts_as_tree that works just like the one you can define on belongs_to #371 [Josh Peek] * Added Base.default_timezone accessor that determines whether to use Time.local (using :local) or Time.utc (using :utc) when pulling dates and times from the database. This is set to :local by default. @@ -4796,7 +4796,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Fixed handling of binary content in blobs and similar fields for Ruby/MySQL and SQLite #409 [xal] -* Fixed a bug in the Ruby/MySQL that caused binary content to be escaped badly and come back mangled #405 [Tobias Luetke] +* Fixed a bug in the Ruby/MySQL that caused binary content to be escaped badly and come back mangled #405 [Tobias Lütke] * Fixed that the const_missing autoload assumes the requested constant is set by require_association and calls const_get to retrieve it. If require_association did not set the constant then const_get will call const_missing, resulting in an infinite loop #380 [Jeremy Kemper] @@ -4837,7 +4837,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Added work-around for PostgreSQL and the problem of getting fixtures to be created from id 1 on each test case. This only works for auto-incrementing primary keys called "id" for now #359 [Scott Baron] -* Added Base#clear_association_cache to empty all the cached associations #347 [Tobias Luetke] +* Added Base#clear_association_cache to empty all the cached associations #347 [Tobias Lütke] * Added more informative exceptions in establish_connection #356 [Jeremy Kemper] @@ -4854,7 +4854,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Added that query benchmarking will only happen if its going to be logged anyway #344 -* Added higher_item and lower_item as public methods for acts_as_list #342 [Tobias Luetke] +* Added higher_item and lower_item as public methods for acts_as_list #342 [Tobias Lütke] * Fixed that options[:counter_sql] was overwritten with interpolated sql rather than original sql #355 [Jeremy Kemper] @@ -4885,7 +4885,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio validates_inclusion_of :age, :in=>0..99 end -* Added acts_as_list that can decorates an existing class with methods like move_higher/lower, move_to_top/bottom. [Tobias Luetke] Example: +* Added acts_as_list that can decorates an existing class with methods like move_higher/lower, move_to_top/bottom. [Tobias Lütke] Example: class TodoItem < ActiveRecord::Base acts_as_list :scope => :todo_list_id @@ -4893,12 +4893,12 @@ in effect. Added :readonly finder constraint. Calling an association collectio end * Added acts_as_tree that can decorates an existing class with a many to many relationship with itself. Perfect for categories in - categories and the likes. [Tobias Luetke] + categories and the likes. [Tobias Lütke] * Added that Active Records will automatically record creation and/or update timestamps of database objects if fields of the names - created_at/created_on or updated_at/updated_on are present. [Tobias Luetke] + created_at/created_on or updated_at/updated_on are present. [Tobias Lütke] -* Added Base.default_error_messages as a hash of all the error messages used in the validates_*_of so they can be changed in one place [Tobias Luetke] +* Added Base.default_error_messages as a hash of all the error messages used in the validates_*_of so they can be changed in one place [Tobias Lütke] * Added automatic transaction block around AssociationCollection.<<, AssociationCollection.delete, and AssociationCollection.destroy_all @@ -4931,13 +4931,13 @@ in effect. Added :readonly finder constraint. Calling an association collectio errors.on("name") # => "must be shorter" * Added Base.validates_format_of that Validates whether the value of the specified attribute is of the correct form by matching - it against the regular expression provided. [Marcel] + it against the regular expression provided. [Marcel Molina Jr.] class Person < ActiveRecord::Base validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/, :on => :create end -* Added Base.validates_length_of that delegates to add_on_boundary_breaking #312 [Tobias Luetke]. Example: +* Added Base.validates_length_of that delegates to add_on_boundary_breaking #312 [Tobias Lütke]. Example: Validates that the specified attribute matches the length restrictions supplied in either: @@ -5156,7 +5156,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Fixed that calling id would create the instance variable for new_records preventing them from being saved correctly [Jeremy Kemper] -* Added sanitization feature to HasManyAssociation#find_all so it works just like Base.find_all [Sam Stephenson/bitsweat] +* Added sanitization feature to HasManyAssociation#find_all so it works just like Base.find_all [Sam Stephenson/Jeremy Kemper] * Added that you can pass overlapping ids to find without getting duplicated records back [Jeremy Kemper] @@ -5166,7 +5166,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Fixed that quotes would break regular non-yaml fixtures [Dmitry Sabanin/daft] -* Fixed fixtures on windows with line endings cause problems under unix / mac [Tobias Luetke] +* Fixed fixtures on windows with line endings cause problems under unix / mac [Tobias Lütke] * Added HasAndBelongsToManyAssociation#find(id) that'll search inside the collection and find the object or record with that id @@ -5287,7 +5287,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio project.milestones << Milestone.find_all end -* Added logging of invalid SQL statements [Suggested by Daniel Von Fange] +* Added logging of invalid SQL statements [Daniel Von Fange] * Added alias Errors#[] for Errors#on, so you can now say person.errors["name"] to retrieve the errors for name [Andreas Schwarz] @@ -5319,7 +5319,7 @@ in effect. Added :readonly finder constraint. Calling an association collectio * Changed class inheritable attributes to not use eval [Caio Chassot] -* Changed Errors#add to now use "invalid" as the default message instead of true, which means full_messages work with those [Marcel Molina Jr] +* Changed Errors#add to now use "invalid" as the default message instead of true, which means full_messages work with those [Marcel Molina Jr.] * Fixed spelling on Base#add_on_boundry_breaking to Base#add_on_boundary_breaking (old naming still works) [Marcel Molina Jr.] @@ -5771,7 +5771,7 @@ _Misc_ *0.8.1* -* Added object-level transactions [Thanks to Austin Ziegler for Transaction::Simple] +* Added object-level transactions [Austin Ziegler] * Changed adapter-specific connection methods to use centralized ActiveRecord::Base.establish_connection, which is parametized through a config hash with symbol keys instead of a regular parameter list. @@ -5806,4 +5806,4 @@ _Misc_ *0.7.6* * Fixed the install.rb to create the lib/active_record/support directory [Spotted by Gavin Sinclair] -* Fixed that has_association? would always return true [Spotted by Daniel Von Fange] +* Fixed that has_association? would always return true [Daniel Von Fange] -- cgit v1.2.3 From c4023cbe206415cf3ca1ca92cd9980a4aa4aed00 Mon Sep 17 00:00:00 2001 From: Daniel Luz Date: Mon, 1 Dec 2008 02:58:39 -0200 Subject: Update documentation for default_scope Signed-off-by: David Heinemeier Hansson --- activerecord/lib/active_record/base.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index a23518b357..87c0002463 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -2052,10 +2052,10 @@ module ActiveRecord #:nodoc: end # Sets the default options for the model. The format of the - # method_scoping argument is the same as in with_scope. + # options argument is the same as in find. # # class Person < ActiveRecord::Base - # default_scope :find => { :order => 'last_name, first_name' } + # default_scope :order => 'last_name, first_name' # end def default_scope(options = {}) self.default_scoping << { :find => options, :create => (options.is_a?(Hash) && options.has_key?(:conditions)) ? options[:conditions] : {} } -- cgit v1.2.3 From 428e77bf0fcee4369cb8d94011141f791b8e2ba9 Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Wed, 17 Dec 2008 23:37:55 +0000 Subject: Make exceptions raise from find_by_foo! have a more helpful message [#1567 state:resolved] --- activerecord/lib/active_record/base.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 87c0002463..dfead0b94f 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1829,7 +1829,7 @@ module ActiveRecord #:nodoc: else find(:#{finder}, options.merge(finder_options)) end - #{'result || raise(RecordNotFound)' if bang} + #{'result || raise(RecordNotFound, "Couldn\'t find #{name} with #{attributes.to_a.collect {|pair| "#{pair.first} = #{pair.second}"}.join(\', \')}")' if bang} end }, __FILE__, __LINE__ send(method_id, *arguments) -- cgit v1.2.3 From 707d0dd3e1e8df7771073670e4257d933d2818f9 Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Wed, 17 Dec 2008 23:39:09 +0000 Subject: Fix preloading of belongs_to with null foreign key generating useless query [#1027 state:resolved] --- activerecord/lib/active_record/association_preload.rb | 1 + activerecord/test/cases/associations/eager_test.rb | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb index 99c3ce5e62..d8aa1051bd 100644 --- a/activerecord/lib/active_record/association_preload.rb +++ b/activerecord/lib/active_record/association_preload.rb @@ -307,6 +307,7 @@ module ActiveRecord klasses_and_ids.each do |klass_and_id| klass_name, id_map = *klass_and_id + next if id_map.empty? klass = klass_name.constantize table_name = klass.quoted_table_name diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 3c8408d14b..2fd51ef03a 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -145,7 +145,7 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_finding_with_includes_on_null_belongs_to_association_with_same_include_includes_only_once post = posts(:welcome) post.update_attributes!(:author => nil) - post = assert_queries(2) { Post.find(post.id, :include => {:author_with_address => :author_address}) } # find the post, then find the author which is null so no query for the address + post = assert_queries(1) { Post.find(post.id, :include => {:author_with_address => :author_address}) } # find the post, then find the author which is null so no query for the author or address assert_no_queries do assert_equal nil, post.author_with_address end @@ -705,4 +705,5 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_order_on_join_table_with_include_and_limit assert_equal 5, Developer.find(:all, :include => 'projects', :order => 'developers_projects.joined_on DESC', :limit => 5).size end + end -- cgit v1.2.3 From 9cf6b1b15e6335134a5af5d9d6296f8d9242e005 Mon Sep 17 00:00:00 2001 From: Emilio Tagua Date: Tue, 2 Dec 2008 13:47:53 -0300 Subject: Add missing model files so tests can run isolated [#1506 state:resolved] Signed-off-by: Frederick Cheung --- .../test/cases/associations/has_many_through_associations_test.rb | 3 +++ 1 file changed, 3 insertions(+) (limited to 'activerecord') 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 a07f4bcbdd..0bfda337b2 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -3,6 +3,9 @@ require 'models/post' require 'models/person' require 'models/reader' require 'models/comment' +require 'models/tag' +require 'models/tagging' +require 'models/author' class HasManyThroughAssociationsTest < ActiveRecord::TestCase fixtures :posts, :readers, :people, :comments, :authors -- cgit v1.2.3 From c9ab7098be7bdd748c0f4a49c8ef015b4aad3108 Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Thu, 18 Dec 2008 19:07:55 +0000 Subject: Ensure :include checks joins when determining if it can preload [#528 state:resolved] --- activerecord/lib/active_record/associations.rb | 43 ++++++++++---- activerecord/test/cases/associations/eager_test.rb | 65 ++++++++++++++++++++++ 2 files changed, 98 insertions(+), 10 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 3fbbea43ed..bc2a88ef7e 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1731,6 +1731,11 @@ module ActiveRecord return sanitize_sql(sql) end + def tables_in_string(string) + return [] if string.blank? + string.scan(/([\.a-zA-Z_]+).?\./).flatten + end + def conditions_tables(options) # look in both sets of conditions conditions = [scope(:find, :conditions), options[:conditions]].inject([]) do |all, cond| @@ -1741,37 +1746,55 @@ module ActiveRecord else all << cond end end - conditions.join(' ').scan(/([\.a-zA-Z_]+).?\./).flatten + tables_in_string(conditions.join(' ')) end def order_tables(options) order = [options[:order], scope(:find, :order) ].join(", ") return [] unless order && order.is_a?(String) - order.scan(/([\.a-zA-Z_]+).?\./).flatten + tables_in_string(order) end def selects_tables(options) select = options[:select] return [] unless select && select.is_a?(String) - select.scan(/"?([\.a-zA-Z_]+)"?.?\./).flatten + tables_in_string(select) + end + + def joined_tables(options) + scope = scope(:find) + joins = options[:joins] + merged_joins = scope && scope[:joins] && joins ? merge_joins(scope[:joins], joins) : (joins || scope && scope[:joins]) + [table_name] + case merged_joins + when Symbol, Hash, Array + if array_of_strings?(merged_joins) + tables_in_string(merged_joins.join(' ')) + else + join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, merged_joins, nil) + [table_name] + join_dependency.join_associations.collect {|join_association| [join_association.aliased_join_table_name, join_association.aliased_table_name]}.flatten.compact + end + else + tables_in_string(merged_joins) + end end # Checks if the conditions reference a table other than the current model table - def include_eager_conditions?(options, tables = nil) - ((tables || conditions_tables(options)) - [table_name]).any? + def include_eager_conditions?(options, tables = nil, joined_tables = nil) + ((tables || conditions_tables(options)) - (joined_tables || joined_tables(options))).any? end # Checks if the query order references a table other than the current model's table. - def include_eager_order?(options, tables = nil) - ((tables || order_tables(options)) - [table_name]).any? + def include_eager_order?(options, tables = nil, joined_tables = nil) + ((tables || order_tables(options)) - (joined_tables || joined_tables(options))).any? end - def include_eager_select?(options) - (selects_tables(options) - [table_name]).any? + def include_eager_select?(options, joined_tables = nil) + (selects_tables(options) - (joined_tables || joined_tables(options))).any? end def references_eager_loaded_tables?(options) - include_eager_order?(options) || include_eager_conditions?(options) || include_eager_select?(options) + joined_tables = joined_tables(options) + include_eager_order?(options, nil, joined_tables) || include_eager_conditions?(options, nil, joined_tables) || include_eager_select?(options, joined_tables) end def using_limitable_reflections?(reflections) diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 2fd51ef03a..42063d18a3 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -1,6 +1,7 @@ require "cases/helper" require 'models/post' require 'models/tagging' +require 'models/tag' require 'models/comment' require 'models/author' require 'models/category' @@ -706,4 +707,68 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_equal 5, Developer.find(:all, :include => 'projects', :order => 'developers_projects.joined_on DESC', :limit => 5).size end + def test_eager_loading_with_order_on_joined_table_preloads + posts = assert_queries(2) do + Post.find(:all, :joins => :comments, :include => :author, :order => 'comments.id DESC') + end + assert_equal posts(:eager_other), posts[0] + assert_equal authors(:mary), assert_no_queries { posts[0].author} + end + + def test_eager_loading_with_conditions_on_joined_table_preloads + posts = assert_queries(2) do + Post.find(:all, :select => 'distinct posts.*', :include => :author, :joins => [:comments], :conditions => "comments.body like 'Thank you%'", :order => 'posts.id') + end + assert_equal [posts(:welcome)], posts + assert_equal authors(:david), assert_no_queries { posts[0].author} + + posts = assert_queries(2) do + Post.find(:all, :select => 'distinct posts.*', :include => :author, :joins => [:comments], :conditions => "comments.body like 'Thank you%'", :order => 'posts.id') + end + assert_equal [posts(:welcome)], posts + assert_equal authors(:david), assert_no_queries { posts[0].author} + + posts = assert_queries(2) do + Post.find(:all, :include => :author, :joins => {:taggings => :tag}, :conditions => "tags.name = 'General'") + end + assert_equal posts(:welcome, :thinking), posts + + posts = assert_queries(2) do + Post.find(:all, :include => :author, :joins => {:taggings => {:tag => :taggings}}, :conditions => "taggings_tags.super_tag_id=2") + end + assert_equal posts(:welcome, :thinking), posts + + end + + def test_eager_loading_with_conditions_on_string_joined_table_preloads + posts = assert_queries(2) do + Post.find(:all, :select => 'distinct posts.*', :include => :author, :joins => "INNER JOIN comments on comments.post_id = posts.id", :conditions => "comments.body like 'Thank you%'", :order => 'posts.id') + end + assert_equal [posts(:welcome)], posts + assert_equal authors(:david), assert_no_queries { posts[0].author} + + posts = assert_queries(2) do + Post.find(:all, :select => 'distinct posts.*', :include => :author, :joins => ["INNER JOIN comments on comments.post_id = posts.id"], :conditions => "comments.body like 'Thank you%'", :order => 'posts.id') + end + assert_equal [posts(:welcome)], posts + assert_equal authors(:david), assert_no_queries { posts[0].author} + + end + + def test_eager_loading_with_select_on_joined_table_preloads + posts = assert_queries(2) do + Post.find(:all, :select => 'posts.*, authors.name as author_name', :include => :comments, :joins => :author, :order => 'posts.id') + end + assert_equal 'David', posts[0].author_name + assert_equal posts(:welcome).comments, assert_no_queries { posts[0].comments} + end + + def test_eager_loading_with_conditions_on_join_model_preloads + authors = assert_queries(2) do + Author.find(:all, :include => :author_address, :joins => :comments, :conditions => "posts.title like 'Welcome%'") + end + assert_equal authors(:david), authors[0] + assert_equal author_addresses(:david_address), authors[0].author_address + end + end -- cgit v1.2.3 From 9c7fe7c6729bbdde4a22f58e7279463092390330 Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Thu, 18 Dec 2008 10:41:45 +0000 Subject: Don't include table_name twice --- activerecord/lib/active_record/associations.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index bc2a88ef7e..3165015f3e 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1771,7 +1771,7 @@ module ActiveRecord tables_in_string(merged_joins.join(' ')) else join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, merged_joins, nil) - [table_name] + join_dependency.join_associations.collect {|join_association| [join_association.aliased_join_table_name, join_association.aliased_table_name]}.flatten.compact + join_dependency.join_associations.collect {|join_association| [join_association.aliased_join_table_name, join_association.aliased_table_name]}.flatten.compact end else tables_in_string(merged_joins) -- cgit v1.2.3 From 8326b95169ae6af3b81f5596107fef9db4bcbbb0 Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Wed, 19 Nov 2008 15:17:40 +0100 Subject: Free MySQL::Result objects after a call to execute [#1416 state:resolved] No freeing Result objects causes the MySQL driver to free result sets at undefined times, this can lead to erratic performance in your application. Signed-off-by: Frederick Cheung --- .../active_record/connection_adapters/mysql_adapter.rb | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb index c3cbdc8c2f..46d4b6c89c 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb @@ -308,6 +308,7 @@ module ActiveRecord rows end + # Executes a SQL query and returns a MySQL::Result object. Note that you have to free the Result object after you're done using it. def execute(sql, name = nil) #:nodoc: log(sql, name) { @connection.query(sql) } rescue ActiveRecord::StatementInvalid => exception @@ -414,7 +415,9 @@ module ActiveRecord def tables(name = nil) #:nodoc: tables = [] - execute("SHOW TABLES", name).each { |field| tables << field[0] } + result = execute("SHOW TABLES", name) + result.each { |field| tables << field[0] } + result.free tables end @@ -425,7 +428,8 @@ module ActiveRecord def indexes(table_name, name = nil)#:nodoc: indexes = [] current_index = nil - execute("SHOW KEYS FROM #{quote_table_name(table_name)}", name).each do |row| + result = execute("SHOW KEYS FROM #{quote_table_name(table_name)}", name) + result.each do |row| if current_index != row[2] next if row[2] == "PRIMARY" # skip the primary key current_index = row[2] @@ -434,13 +438,16 @@ module ActiveRecord indexes.last.columns << row[4] end + result.free indexes end def columns(table_name, name = nil)#:nodoc: sql = "SHOW FIELDS FROM #{quote_table_name(table_name)}" columns = [] - execute(sql, name).each { |field| columns << MysqlColumn.new(field[0], field[4], field[1], field[2] == "YES") } + result = execute(sql, name) + result.each { |field| columns << MysqlColumn.new(field[0], field[4], field[1], field[2] == "YES") } + result.free columns end @@ -521,9 +528,11 @@ module ActiveRecord # Returns a table's primary key and belonging sequence. def pk_and_sequence_for(table) #:nodoc: keys = [] - execute("describe #{quote_table_name(table)}").each_hash do |h| + result = execute("describe #{quote_table_name(table)}") + result.each_hash do |h| keys << h["Field"]if h["Key"] == "PRI" end + result.free keys.length == 1 ? [keys.first, nil] : nil end -- cgit v1.2.3 From a9422cc1db9501a80ecf2c25a5d3b0c4f4f32763 Mon Sep 17 00:00:00 2001 From: Matt Jones Date: Tue, 2 Dec 2008 16:21:21 -0500 Subject: Fix preloading of has_one :through associations on belongs_to [#1507 state:resolved] Signed-off-by: Frederick Cheung --- activerecord/lib/active_record/association_preload.rb | 15 ++++++++++++--- .../associations/association_collection.rb | 6 +++++- .../associations/has_one_through_associations_test.rb | 17 ++++++++++++++++- activerecord/test/fixtures/member_types.yml | 6 ++++++ activerecord/test/fixtures/members.yml | 4 +++- activerecord/test/models/member.rb | 1 + activerecord/test/models/member_detail.rb | 1 + activerecord/test/models/member_type.rb | 3 +++ activerecord/test/schema/schema.rb | 5 +++++ 9 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 activerecord/test/fixtures/member_types.yml create mode 100644 activerecord/test/models/member_type.rb (limited to 'activerecord') diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb index d8aa1051bd..7b1b2d9ad9 100644 --- a/activerecord/lib/active_record/association_preload.rb +++ b/activerecord/lib/active_record/association_preload.rb @@ -204,9 +204,18 @@ module ActiveRecord unless through_records.empty? source = reflection.source_reflection.name through_records.first.class.preload_associations(through_records, source) - through_records.each do |through_record| - add_preloaded_record_to_collection(id_to_record_map[through_record[through_primary_key].to_s], - reflection.name, through_record.send(source)) + if through_reflection.macro == :belongs_to + rev_id_to_record_map, rev_ids = construct_id_map(records, through_primary_key) + rev_primary_key = through_reflection.klass.primary_key + through_records.each do |through_record| + add_preloaded_record_to_collection(rev_id_to_record_map[through_record[rev_primary_key].to_s], + reflection.name, through_record.send(source)) + end + else + through_records.each do |through_record| + add_preloaded_record_to_collection(id_to_record_map[through_record[through_primary_key].to_s], + reflection.name, through_record.send(source)) + end end end else diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 0ff91fbdf8..0fefec1216 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -83,7 +83,11 @@ module ActiveRecord def to_ary load_target - @target.to_ary + if @target.is_a?(Array) + @target.to_ary + else + Array(@target) + end end def reset diff --git a/activerecord/test/cases/associations/has_one_through_associations_test.rb b/activerecord/test/cases/associations/has_one_through_associations_test.rb index 7d418de965..f65d76e2ce 100644 --- a/activerecord/test/cases/associations/has_one_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_one_through_associations_test.rb @@ -1,5 +1,6 @@ require "cases/helper" require 'models/club' +require 'models/member_type' require 'models/member' require 'models/membership' require 'models/sponsor' @@ -7,7 +8,7 @@ require 'models/organization' require 'models/member_detail' class HasOneThroughAssociationsTest < ActiveRecord::TestCase - fixtures :members, :clubs, :memberships, :sponsors, :organizations + fixtures :member_types, :members, :clubs, :memberships, :sponsors, :organizations def setup @member = members(:groucho) @@ -158,4 +159,18 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase assert @new_organization.members.include?(@member) end + def test_preloading_has_one_through_on_belongs_to + assert_not_nil @member.member_type + @organization = organizations(:nsa) + @member_detail = MemberDetail.new + @member.member_detail = @member_detail + @member.organization = @organization + @member_details = assert_queries(3) do + MemberDetail.find(:all, :include => :member_type) + end + @new_detail = @member_details[0] + assert @new_detail.loaded_member_type? + assert_not_nil assert_no_queries { @new_detail.member_type } + end + end diff --git a/activerecord/test/fixtures/member_types.yml b/activerecord/test/fixtures/member_types.yml new file mode 100644 index 0000000000..797a57430c --- /dev/null +++ b/activerecord/test/fixtures/member_types.yml @@ -0,0 +1,6 @@ +founding: + id: 1 + name: Founding +provisional: + id: 2 + name: Provisional diff --git a/activerecord/test/fixtures/members.yml b/activerecord/test/fixtures/members.yml index 67a6cc459a..6db945e61d 100644 --- a/activerecord/test/fixtures/members.yml +++ b/activerecord/test/fixtures/members.yml @@ -1,4 +1,6 @@ groucho: name: Groucho Marx + member_type_id: 1 some_other_guy: - name: Englebert Humperdink \ No newline at end of file + name: Englebert Humperdink + member_type_id: 2 diff --git a/activerecord/test/models/member.rb b/activerecord/test/models/member.rb index 77a37abb38..255fb569d7 100644 --- a/activerecord/test/models/member.rb +++ b/activerecord/test/models/member.rb @@ -8,4 +8,5 @@ class Member < ActiveRecord::Base has_one :sponsor_club, :through => :sponsor has_one :member_detail has_one :organization, :through => :member_detail + belongs_to :member_type end \ No newline at end of file diff --git a/activerecord/test/models/member_detail.rb b/activerecord/test/models/member_detail.rb index e731454556..94f59e5794 100644 --- a/activerecord/test/models/member_detail.rb +++ b/activerecord/test/models/member_detail.rb @@ -1,4 +1,5 @@ class MemberDetail < ActiveRecord::Base belongs_to :member belongs_to :organization + has_one :member_type, :through => :member end diff --git a/activerecord/test/models/member_type.rb b/activerecord/test/models/member_type.rb new file mode 100644 index 0000000000..a13561c72a --- /dev/null +++ b/activerecord/test/models/member_type.rb @@ -0,0 +1,3 @@ +class MemberType < ActiveRecord::Base + has_many :members +end diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 6217e3bc1c..fbacc692b4 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -195,6 +195,7 @@ ActiveRecord::Schema.define do create_table :members, :force => true do |t| t.string :name + t.integer :member_type_id end create_table :member_details, :force => true do |t| @@ -210,6 +211,10 @@ ActiveRecord::Schema.define do t.string :type end + create_table :member_types, :force => true do |t| + t.string :name + end + create_table :references, :force => true do |t| t.integer :person_id t.integer :job_id -- cgit v1.2.3 From 8a92cdc8638d1f91aaa55fc47743a6210ad2181b Mon Sep 17 00:00:00 2001 From: Murray Steele Date: Fri, 19 Dec 2008 13:27:34 +0000 Subject: Add a repair_helper to repair changes to the validations inside validations_test.rb [#674 state:resolved] Many of the tests in validations_test would add a new validation to models. However, only Topic was being reset with a fairly aggressive clearing of all validations. None of the other models being used however were recieving the same treatment. Now we use repair_validations(Topic) for the whole test case because most test cases use Topic and then the block form of repair_validations() inside any tests that use other models. Signed-off-by: Pratik Naik --- activerecord/test/cases/helper.rb | 4 + activerecord/test/cases/validations_test.rb | 351 +++++++++++++++------------- 2 files changed, 195 insertions(+), 160 deletions(-) (limited to 'activerecord') diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb index afba715448..2043138ca3 100644 --- a/activerecord/test/cases/helper.rb +++ b/activerecord/test/cases/helper.rb @@ -9,6 +9,8 @@ require 'active_record/test_case' require 'active_record/fixtures' require 'connection' +require 'cases/repair_helper' + # Show backtraces for deprecated behavior for quicker cleanup. ActiveSupport::Deprecation.debug = true @@ -60,6 +62,8 @@ end class ActiveSupport::TestCase include ActiveRecord::TestFixtures + include ActiveRecord::Testing::RepairHelper + self.fixture_path = FIXTURES_ROOT self.use_instantiated_fixtures = false self.use_transactional_fixtures = true diff --git a/activerecord/test/cases/validations_test.rb b/activerecord/test/cases/validations_test.rb index c049659327..380d8ac260 100644 --- a/activerecord/test/cases/validations_test.rb +++ b/activerecord/test/cases/validations_test.rb @@ -6,6 +6,8 @@ require 'models/person' require 'models/developer' require 'models/warehouse_thing' require 'models/guid' +require 'models/owner' +require 'models/pet' # The following methods in Topic are used in test_conditional_validation_* class Topic @@ -31,10 +33,6 @@ class UniqueReply < Reply validates_uniqueness_of :content, :scope => 'parent_id' end -class PlagiarizedReply < Reply - validates_acceptance_of :author_name -end - class SillyUniqueReply < UniqueReply end @@ -58,11 +56,9 @@ end class ValidationsTest < ActiveRecord::TestCase fixtures :topics, :developers, 'warehouse-things' - def setup - Topic.instance_variable_set("@validate_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - Topic.instance_variable_set("@validate_on_create_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - Topic.instance_variable_set("@validate_on_update_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - end + # Most of the tests mess with the validations of Topic, so lets repair it all the time. + # Other classes we mess with will be dealt with in the specific tests + repair_validations(Topic) def test_single_field_validation r = Reply.new @@ -134,7 +130,7 @@ class ValidationsTest < ActiveRecord::TestCase Reply.create!([ { "title" => "OK" }, { "title" => "Wrong Create" }]) end end - + def test_exception_on_create_bang_with_block assert_raises(ActiveRecord::RecordInvalid) do Reply.create!({ "title" => "OK" }) do |r| @@ -142,7 +138,7 @@ class ValidationsTest < ActiveRecord::TestCase end end end - + def test_exception_on_create_bang_many_with_block assert_raises(ActiveRecord::RecordInvalid) do Reply.create!([{ "title" => "OK" }, { "title" => "Wrong Create" }]) do |r| @@ -229,21 +225,16 @@ class ValidationsTest < ActiveRecord::TestCase end def test_validates_each - perform = true hits = 0 Topic.validates_each(:title, :content, [:title, :content]) do |record, attr| - if perform - record.errors.add attr, 'gotcha' - hits += 1 - end + record.errors.add attr, 'gotcha' + hits += 1 end t = Topic.new("title" => "valid", "content" => "whatever") assert !t.save assert_equal 4, hits assert_equal %w(gotcha gotcha), t.errors.on(:title) assert_equal %w(gotcha gotcha), t.errors.on(:content) - ensure - perform = false end def test_no_title_confirmation @@ -315,8 +306,12 @@ class ValidationsTest < ActiveRecord::TestCase end def test_validates_acceptance_of_as_database_column - reply = PlagiarizedReply.create("author_name" => "Dan Brown") - assert_equal "Dan Brown", reply["author_name"] + repair_validations(Reply) do + Reply.validates_acceptance_of(:author_name) + + reply = Reply.create("author_name" => "Dan Brown") + assert_equal "Dan Brown", reply["author_name"] + end end def test_validates_acceptance_of_with_non_existant_table @@ -372,22 +367,24 @@ class ValidationsTest < ActiveRecord::TestCase end def test_validate_uniqueness_with_scope - Reply.validates_uniqueness_of(:content, :scope => "parent_id") + repair_validations(Reply) do + Reply.validates_uniqueness_of(:content, :scope => "parent_id") - t = Topic.create("title" => "I'm unique!") + t = Topic.create("title" => "I'm unique!") - r1 = t.replies.create "title" => "r1", "content" => "hello world" - assert r1.valid?, "Saving r1" + r1 = t.replies.create "title" => "r1", "content" => "hello world" + assert r1.valid?, "Saving r1" - r2 = t.replies.create "title" => "r2", "content" => "hello world" - assert !r2.valid?, "Saving r2 first time" + r2 = t.replies.create "title" => "r2", "content" => "hello world" + assert !r2.valid?, "Saving r2 first time" - r2.content = "something else" - assert r2.save, "Saving r2 second time" + r2.content = "something else" + assert r2.save, "Saving r2 second time" - t2 = Topic.create("title" => "I'm unique too!") - r3 = t2.replies.create "title" => "r3", "content" => "hello world" - assert r3.valid?, "Saving r3" + t2 = Topic.create("title" => "I'm unique too!") + r3 = t2.replies.create "title" => "r3", "content" => "hello world" + assert r3.valid?, "Saving r3" + end end def test_validate_uniqueness_scoped_to_defining_class @@ -406,27 +403,29 @@ class ValidationsTest < ActiveRecord::TestCase end def test_validate_uniqueness_with_scope_array - Reply.validates_uniqueness_of(:author_name, :scope => [:author_email_address, :parent_id]) + repair_validations(Reply) do + Reply.validates_uniqueness_of(:author_name, :scope => [:author_email_address, :parent_id]) - t = Topic.create("title" => "The earth is actually flat!") + t = Topic.create("title" => "The earth is actually flat!") - r1 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply" - assert r1.valid?, "Saving r1" + r1 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply" + assert r1.valid?, "Saving r1" - r2 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply again..." - assert !r2.valid?, "Saving r2. Double reply by same author." + r2 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply again..." + assert !r2.valid?, "Saving r2. Double reply by same author." - r2.author_email_address = "jeremy_alt_email@rubyonrails.com" - assert r2.save, "Saving r2 the second time." + r2.author_email_address = "jeremy_alt_email@rubyonrails.com" + assert r2.save, "Saving r2 the second time." - r3 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy_alt_email@rubyonrails.com", "title" => "You're wrong", "content" => "It's cubic" - assert !r3.valid?, "Saving r3" + r3 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy_alt_email@rubyonrails.com", "title" => "You're wrong", "content" => "It's cubic" + assert !r3.valid?, "Saving r3" - r3.author_name = "jj" - assert r3.save, "Saving r3 the second time." + r3.author_name = "jj" + assert r3.save, "Saving r3 the second time." - r3.author_name = "jeremy" - assert !r3.save, "Saving r3 the third time." + r3.author_name = "jeremy" + assert !r3.save, "Saving r3 the third time." + end end def test_validate_case_insensitive_uniqueness @@ -523,10 +522,12 @@ class ValidationsTest < ActiveRecord::TestCase end def test_validate_uniqueness_with_columns_which_are_sql_keywords - Guid.validates_uniqueness_of :key - g = Guid.new - g.key = "foo" - assert_nothing_raised { !g.valid? } + repair_validations(Guid) do + Guid.validates_uniqueness_of :key + g = Guid.new + g.key = "foo" + assert_nothing_raised { !g.valid? } + end end def test_validate_straight_inheritance_uniqueness @@ -648,10 +649,12 @@ class ValidationsTest < ActiveRecord::TestCase end def test_numericality_with_getter_method - Developer.validates_numericality_of( :salary ) - developer = Developer.new("name" => "michael", "salary" => nil) - developer.instance_eval("def salary; read_attribute('salary') ? read_attribute('salary') : 100000; end") - assert developer.valid? + repair_validations(Developer) do + Developer.validates_numericality_of( :salary ) + developer = Developer.new("name" => "michael", "salary" => nil) + developer.instance_eval("def salary; read_attribute('salary') ? read_attribute('salary') : 100000; end") + assert developer.valid? + end end def test_validates_length_of_with_allow_nil @@ -684,10 +687,12 @@ class ValidationsTest < ActiveRecord::TestCase end def test_numericality_with_allow_nil_and_getter_method - Developer.validates_numericality_of( :salary, :allow_nil => true) - developer = Developer.new("name" => "michael", "salary" => nil) - developer.instance_eval("def salary; read_attribute('salary') ? read_attribute('salary') : 100000; end") - assert developer.valid? + repair_validations(Developer) do + Developer.validates_numericality_of( :salary, :allow_nil => true) + developer = Developer.new("name" => "michael", "salary" => nil) + developer.instance_eval("def salary; read_attribute('salary') ? read_attribute('salary') : 100000; end") + assert developer.valid? + end end def test_validates_exclusion_of @@ -892,26 +897,30 @@ class ValidationsTest < ActiveRecord::TestCase end def test_validates_size_of_association - assert_nothing_raised { Topic.validates_size_of :replies, :minimum => 1 } - t = Topic.new('title' => 'noreplies', 'content' => 'whatever') - assert !t.save - assert t.errors.on(:replies) - reply = t.replies.build('title' => 'areply', 'content' => 'whateveragain') - assert t.valid? + repair_validations(Owner) do + assert_nothing_raised { Owner.validates_size_of :pets, :minimum => 1 } + o = Owner.new('name' => 'nopets') + assert !o.save + assert o.errors.on(:pets) + pet = o.pets.build('name' => 'apet') + assert o.valid? + end end def test_validates_size_of_association_using_within - assert_nothing_raised { Topic.validates_size_of :replies, :within => 1..2 } - t = Topic.new('title' => 'noreplies', 'content' => 'whatever') - assert !t.save - assert t.errors.on(:replies) - - reply = t.replies.build('title' => 'areply', 'content' => 'whateveragain') - assert t.valid? - - 2.times { t.replies.build('title' => 'areply', 'content' => 'whateveragain') } - assert !t.save - assert t.errors.on(:replies) + repair_validations(Owner) do + assert_nothing_raised { Owner.validates_size_of :pets, :within => 1..2 } + o = Owner.new('name' => 'nopets') + assert !o.save + assert o.errors.on(:pets) + + pet = o.pets.build('name' => 'apet') + assert o.valid? + + 2.times { o.pets.build('name' => 'apet') } + assert !o.save + assert o.errors.on(:pets) + end end def test_validates_length_of_nasty_params @@ -1102,13 +1111,15 @@ class ValidationsTest < ActiveRecord::TestCase end def test_validates_size_of_association_utf8 - with_kcode('UTF8') do - assert_nothing_raised { Topic.validates_size_of :replies, :minimum => 1 } - t = Topic.new('title' => 'あいうえお', 'content' => 'かきくけこ') - assert !t.save - assert t.errors.on(:replies) - t.replies.build('title' => 'あいうえお', 'content' => 'かきくけこ') - assert t.valid? + repair_validations(Owner) do + with_kcode('UTF8') do + assert_nothing_raised { Owner.validates_size_of :pets, :minimum => 1 } + o = Owner.new('name' => 'あいうえおかきくけこ') + assert !o.save + assert o.errors.on(:pets) + o.pets.build('name' => 'あいうえおかきくけこ') + assert o.valid? + end end end @@ -1127,14 +1138,16 @@ class ValidationsTest < ActiveRecord::TestCase end def test_validates_associated_one - Reply.validates_associated( :topic ) - Topic.validates_presence_of( :content ) - r = Reply.new("title" => "A reply", "content" => "with content!") - r.topic = Topic.create("title" => "uhohuhoh") - assert !r.valid? - assert r.errors.on(:topic) - r.topic.content = "non-empty" - assert r.valid? + repair_validations(Reply) do + Reply.validates_associated( :topic ) + Topic.validates_presence_of( :content ) + r = Reply.new("title" => "A reply", "content" => "with content!") + r.topic = Topic.create("title" => "uhohuhoh") + assert !r.valid? + assert r.errors.on(:topic) + r.topic.content = "non-empty" + assert r.valid? + end end def test_validate_block @@ -1158,85 +1171,105 @@ class ValidationsTest < ActiveRecord::TestCase end def test_validates_acceptance_of_with_custom_error_using_quotes - Developer.validates_acceptance_of :salary, :message=> "This string contains 'single' and \"double\" quotes" - d = Developer.new - d.salary = "0" - assert !d.valid? - assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:salary).last + repair_validations(Developer) do + Developer.validates_acceptance_of :salary, :message=> "This string contains 'single' and \"double\" quotes" + d = Developer.new + d.salary = "0" + assert !d.valid? + assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:salary).last + end end def test_validates_confirmation_of_with_custom_error_using_quotes - Developer.validates_confirmation_of :name, :message=> "confirm 'single' and \"double\" quotes" - d = Developer.new - d.name = "John" - d.name_confirmation = "Johnny" - assert !d.valid? - assert_equal "confirm 'single' and \"double\" quotes", d.errors.on(:name) + repair_validations(Developer) do + Developer.validates_confirmation_of :name, :message=> "confirm 'single' and \"double\" quotes" + d = Developer.new + d.name = "John" + d.name_confirmation = "Johnny" + assert !d.valid? + assert_equal "confirm 'single' and \"double\" quotes", d.errors.on(:name) + end end def test_validates_format_of_with_custom_error_using_quotes - Developer.validates_format_of :name, :with => /^(A-Z*)$/, :message=> "format 'single' and \"double\" quotes" - d = Developer.new - d.name = d.name_confirmation = "John 32" - assert !d.valid? - assert_equal "format 'single' and \"double\" quotes", d.errors.on(:name) + repair_validations(Developer) do + Developer.validates_format_of :name, :with => /^(A-Z*)$/, :message=> "format 'single' and \"double\" quotes" + d = Developer.new + d.name = d.name_confirmation = "John 32" + assert !d.valid? + assert_equal "format 'single' and \"double\" quotes", d.errors.on(:name) + end end def test_validates_inclusion_of_with_custom_error_using_quotes - Developer.validates_inclusion_of :salary, :in => 1000..80000, :message=> "This string contains 'single' and \"double\" quotes" - d = Developer.new - d.salary = "90,000" - assert !d.valid? - assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:salary).last + repair_validations(Developer) do + Developer.validates_inclusion_of :salary, :in => 1000..80000, :message=> "This string contains 'single' and \"double\" quotes" + d = Developer.new + d.salary = "90,000" + assert !d.valid? + assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:salary).last + end end def test_validates_length_of_with_custom_too_long_using_quotes - Developer.validates_length_of :name, :maximum => 4, :too_long=> "This string contains 'single' and \"double\" quotes" - d = Developer.new - d.name = "Jeffrey" - assert !d.valid? - assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:name).last + repair_validations(Developer) do + Developer.validates_length_of :name, :maximum => 4, :too_long=> "This string contains 'single' and \"double\" quotes" + d = Developer.new + d.name = "Jeffrey" + assert !d.valid? + assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:name) + end end def test_validates_length_of_with_custom_too_short_using_quotes - Developer.validates_length_of :name, :minimum => 4, :too_short=> "This string contains 'single' and \"double\" quotes" - d = Developer.new - d.name = "Joe" - assert !d.valid? - assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:name).last + repair_validations(Developer) do + Developer.validates_length_of :name, :minimum => 4, :too_short=> "This string contains 'single' and \"double\" quotes" + d = Developer.new + d.name = "Joe" + assert !d.valid? + assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:name) + end end def test_validates_length_of_with_custom_message_using_quotes - Developer.validates_length_of :name, :minimum => 4, :message=> "This string contains 'single' and \"double\" quotes" - d = Developer.new - d.name = "Joe" - assert !d.valid? - assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:name).last + repair_validations(Developer) do + Developer.validates_length_of :name, :minimum => 4, :message=> "This string contains 'single' and \"double\" quotes" + d = Developer.new + d.name = "Joe" + assert !d.valid? + assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:name) + end end def test_validates_presence_of_with_custom_message_using_quotes - Developer.validates_presence_of :non_existent, :message=> "This string contains 'single' and \"double\" quotes" - d = Developer.new - d.name = "Joe" - assert !d.valid? - assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:non_existent) + repair_validations(Developer) do + Developer.validates_presence_of :non_existent, :message=> "This string contains 'single' and \"double\" quotes" + d = Developer.new + d.name = "Joe" + assert !d.valid? + assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:non_existent) + end end def test_validates_uniqueness_of_with_custom_message_using_quotes - Developer.validates_uniqueness_of :name, :message=> "This string contains 'single' and \"double\" quotes" - d = Developer.new - d.name = "David" - assert !d.valid? - assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:name).last + repair_validations(Developer) do + Developer.validates_uniqueness_of :name, :message=> "This string contains 'single' and \"double\" quotes" + d = Developer.new + d.name = "David" + assert !d.valid? + assert_equal "This string contains 'single' and \"double\" quotes", d.errors.on(:name) + end end def test_validates_associated_with_custom_message_using_quotes - Reply.validates_associated :topic, :message=> "This string contains 'single' and \"double\" quotes" - Topic.validates_presence_of :content - r = Reply.create("title" => "A reply", "content" => "with content!") - r.topic = Topic.create("title" => "uhohuhoh") - assert !r.valid? - assert_equal "This string contains 'single' and \"double\" quotes", r.errors.on(:topic).last + repair_validations(Reply) do + Reply.validates_associated :topic, :message=> "This string contains 'single' and \"double\" quotes" + Topic.validates_presence_of :content + r = Reply.create("title" => "A reply", "content" => "with content!") + r.topic = Topic.create("title" => "uhohuhoh") + assert !r.valid? + assert_equal "This string contains 'single' and \"double\" quotes", r.errors.on(:topic) + end end def test_if_validation_using_method_true @@ -1346,13 +1379,15 @@ class ValidationsTest < ActiveRecord::TestCase end def test_validates_associated_missing - Reply.validates_presence_of(:topic) - r = Reply.create("title" => "A reply", "content" => "with content!") - assert !r.valid? - assert r.errors.on(:topic) - - r.topic = Topic.find :first - assert r.valid? + repair_validations(Reply) do + Reply.validates_presence_of(:topic) + r = Reply.create("title" => "A reply", "content" => "with content!") + assert !r.valid? + assert r.errors.on(:topic) + + r.topic = Topic.find :first + assert r.valid? + end end def test_errors_to_xml @@ -1364,14 +1399,14 @@ class ValidationsTest < ActiveRecord::TestCase assert xml.include?("Content Empty") end - def test_validation_order - Topic.validates_presence_of :title - Topic.validates_length_of :title, :minimum => 2 + def test_validation_order + Topic.validates_presence_of :title + Topic.validates_length_of :title, :minimum => 2 - t = Topic.new("title" => "") - assert !t.valid? - assert_equal "can't be blank", t.errors.on("title").first - end + t = Topic.new("title" => "") + assert !t.valid? + assert_equal "can't be blank", t.errors.on("title").first + end # previous implementation of validates_presence_of eval'd the # string with the wrong binding, this regression test is to @@ -1423,11 +1458,7 @@ class ValidatesNumericalityTest < ActiveRecord::TestCase JUNK = ["not a number", "42 not a number", "0xdeadbeef", "00-1", "--3", "+-3", "+3-1", "-+019.0", "12.12.13.12", "123\nnot a number"] INFINITY = [1.0/0.0] - def setup - Topic.instance_variable_set("@validate_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - Topic.instance_variable_set("@validate_on_create_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - Topic.instance_variable_set("@validate_on_update_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - end + repair_validations(Topic) def test_default_validates_numericality_of Topic.validates_numericality_of :approved -- cgit v1.2.3 From 89b75814045e811d52b19278ae27b5f45c6d9dd6 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 19 Dec 2008 13:52:21 +0000 Subject: Add repair_helper.rb file I forgot in previous commit 8a92cd --- activerecord/test/cases/repair_helper.rb | 50 ++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 activerecord/test/cases/repair_helper.rb (limited to 'activerecord') diff --git a/activerecord/test/cases/repair_helper.rb b/activerecord/test/cases/repair_helper.rb new file mode 100644 index 0000000000..0155668811 --- /dev/null +++ b/activerecord/test/cases/repair_helper.rb @@ -0,0 +1,50 @@ +module ActiveRecord + module Testing + module RepairHelper + def self.included(base) + base.class_eval do + extend ClassMethods + end + end + + module Toolbox + def self.record_validations(*model_classes) + model_classes.inject({}) do |repair, klass| + repair[klass] ||= {} + [:validate, :validate_on_create, :validate_on_update].each do |callback| + the_callback = klass.instance_variable_get("@#{callback.to_s}_callbacks") + repair[klass][callback] = (the_callback.nil? ? nil : the_callback.dup) + end + repair + end + end + + def self.reset_validations(recorded) + recorded.each do |klass, repairs| + [:validate, :validate_on_create, :validate_on_update].each do |callback| + klass.instance_variable_set("@#{callback.to_s}_callbacks", repairs[callback]) + end + end + end + end + + module ClassMethods + def repair_validations(*model_classes) + setup do + @validation_repairs = ActiveRecord::Testing::RepairHelper::Toolbox.record_validations(*model_classes) + end + teardown do + ActiveRecord::Testing::RepairHelper::Toolbox.reset_validations(@validation_repairs) + end + end + end + + def repair_validations(*model_classes, &block) + validation_repairs = ActiveRecord::Testing::RepairHelper::Toolbox.record_validations(*model_classes) + return block.call + ensure + ActiveRecord::Testing::RepairHelper::Toolbox.reset_validations(validation_repairs) + end + end + end +end -- cgit v1.2.3 From c3f53f412cd170fc295b46e48aa81837ad15ec83 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 19 Dec 2008 14:27:43 +0000 Subject: Merge docrails --- activerecord/lib/active_record/associations.rb | 10 +++++----- activerecord/lib/active_record/base.rb | 3 +-- .../connection_adapters/abstract/connection_specification.rb | 1 + .../connection_adapters/abstract/schema_definitions.rb | 4 +++- activerecord/lib/active_record/validations.rb | 6 +++--- 5 files changed, 13 insertions(+), 11 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 3165015f3e..3cee9c7af2 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -153,7 +153,7 @@ module ActiveRecord # #others.destroy_all | X | X | X # #others.find(*args) | X | X | X # #others.find_first | X | | - # #others.exist? | X | X | X + # #others.exists? | X | X | X # #others.uniq | X | X | X # #others.reset | X | X | X # @@ -652,7 +652,7 @@ module ActiveRecord # Returns the number of associated objects. # [collection.find(...)] # Finds an associated object according to the same rules as ActiveRecord::Base.find. - # [collection.exist?(...)] + # [collection.exists?(...)] # Checks whether an associated object with the given conditions exists. # Uses the same rules as ActiveRecord::Base.exists?. # [collection.build(attributes = {}, ...)] @@ -682,7 +682,7 @@ module ActiveRecord # * Firm#clients.empty? (similar to firm.clients.size == 0) # * Firm#clients.size (similar to Client.count "firm_id = #{id}") # * Firm#clients.find (similar to Client.find(id, :conditions => "firm_id = #{id}")) - # * Firm#clients.exist?(:name => 'ACME') (similar to Client.exist?(:name => 'ACME', :firm_id => firm.id)) + # * Firm#clients.exists?(:name => 'ACME') (similar to Client.exists?(:name => 'ACME', :firm_id => firm.id)) # * Firm#clients.build (similar to Client.new("firm_id" => id)) # * Firm#clients.create (similar to c = Client.new("firm_id" => id); c.save; c) # The declaration can also include an options hash to specialize the behavior of the association. @@ -1107,7 +1107,7 @@ module ActiveRecord # Finds an associated object responding to the +id+ and that # meets the condition that it has to be associated with this object. # Uses the same rules as ActiveRecord::Base.find. - # [collection.exist?(...)] + # [collection.exists?(...)] # Checks whether an associated object with the given conditions exists. # Uses the same rules as ActiveRecord::Base.exists?. # [collection.build(attributes = {})] @@ -1133,7 +1133,7 @@ module ActiveRecord # * Developer#projects.empty? # * Developer#projects.size # * Developer#projects.find(id) - # * Developer#clients.exist?(...) + # * Developer#clients.exists?(...) # * Developer#projects.build (similar to Project.new("project_id" => id)) # * Developer#projects.create (similar to c = Project.new("project_id" => id); c.save; c) # The declaration may include an options hash to specialize the behavior of the association. diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index dfead0b94f..aa6013583d 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -811,8 +811,7 @@ module ActiveRecord #:nodoc: # # ==== Parameters # - # * +updates+ - A string of column and value pairs that will be set on any records that match conditions. - # What goes into the SET clause. + # * +updates+ - A string of column and value pairs that will be set on any records that match conditions. This creates the SET clause of the generated SQL. # * +conditions+ - An SQL fragment like "administrator = 1" or [ "user_name = ?", username ]. See conditions in the intro for more info. # * +options+ - Additional options are :limit and :order, see the examples for usage. # diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb index ccb79f547a..bbc290f721 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb @@ -123,6 +123,7 @@ module ActiveRecord connection_handler.retrieve_connection(self) end + # Returns true if +ActiveRecord+ is connected. def connected? connection_handler.connected?(self) end diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index 58992f91da..fe9cbcf024 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -32,10 +32,12 @@ module ActiveRecord @primary = nil end + # Returns +true+ if the column is either of type string or text. def text? type == :string || type == :text end + # Returns +true+ if the column is either of type integer, float or decimal. def number? type == :integer || type == :float || type == :decimal end @@ -295,7 +297,7 @@ module ActiveRecord # puts t.class # => "ActiveRecord::ConnectionAdapters::TableDefinition" # end # end - # + # # def self.down # ... # end diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index 4b275ddd70..617b3f440f 100644 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -1049,15 +1049,15 @@ module ActiveRecord protected # Overwrite this method for validation checks on all saves and use Errors.add(field, msg) for invalid attributes. - def validate #:doc: + def validate end # Overwrite this method for validation checks used only on creation. - def validate_on_create #:doc: + def validate_on_create end # Overwrite this method for validation checks used only on updates. - def validate_on_update # :doc: + def validate_on_update end end end -- cgit v1.2.3 From c092dbef50ba207174a94b7e0beb7782a3d86649 Mon Sep 17 00:00:00 2001 From: Emilio Tagua Date: Sat, 20 Dec 2008 17:05:53 -0300 Subject: Add missing fixture to allow reload models test to run isolated [#1609 state:resolved] Signed-off-by: Pratik Naik --- activerecord/test/cases/reload_models_test.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/test/cases/reload_models_test.rb b/activerecord/test/cases/reload_models_test.rb index 411b5f6afa..0d16a3526f 100644 --- a/activerecord/test/cases/reload_models_test.rb +++ b/activerecord/test/cases/reload_models_test.rb @@ -3,6 +3,8 @@ require 'models/owner' require 'models/pet' class ReloadModelsTest < ActiveRecord::TestCase + fixtures :pets + def test_has_one_with_reload pet = Pet.find_by_name('parrot') pet.owner = Owner.find_by_name('ashley') @@ -17,4 +19,4 @@ class ReloadModelsTest < ActiveRecord::TestCase pet.owner = Owner.find_by_name('ashley') assert_equal pet.owner, Owner.find_by_name('ashley') end -end \ No newline at end of file +end -- cgit v1.2.3 From 75a133f92ff7e27b83032babf829d8a58803bb3c Mon Sep 17 00:00:00 2001 From: Karthik Krishnan Date: Sat, 20 Dec 2008 20:52:48 +0000 Subject: Fix has many through not quoting table names [#1163 state:resolved] Signed-off-by: Frederick Cheung --- activerecord/lib/active_record/associations.rb | 2 +- .../lib/active_record/associations/has_many_through_association.rb | 6 +++--- .../test/cases/associations/has_many_through_associations_test.rb | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 3cee9c7af2..07bc50c886 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -2198,7 +2198,7 @@ module ActiveRecord protected def aliased_table_name_for(name, suffix = nil) - if !parent.table_joins.blank? && parent.table_joins.to_s.downcase =~ %r{join(\s+\w+)?\s+#{name.downcase}\son} + if !parent.table_joins.blank? && parent.table_joins.to_s.downcase =~ %r{join(\s+\w+)?\s+#{active_record.connection.quote_table_name name.downcase}\son} @join_dependency.table_aliases[name] += 1 end 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 a0bb3a45b0..2eeeb28d1f 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -160,9 +160,9 @@ module ActiveRecord end "INNER JOIN %s ON %s.%s = %s.%s %s #{@reflection.options[:joins]} #{custom_joins}" % [ - @reflection.through_reflection.table_name, - @reflection.table_name, reflection_primary_key, - @reflection.through_reflection.table_name, source_primary_key, + @reflection.through_reflection.quoted_table_name, + @reflection.quoted_table_name, reflection_primary_key, + @reflection.through_reflection.quoted_table_name, source_primary_key, polymorphic_join ] 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 0bfda337b2..ad6a5d6840 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -204,6 +204,10 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase assert_equal 2, people(:michael).posts.count(:include => :readers) end + def test_inner_join_with_quoted_table_name + assert_equal 2, people(:michael).jobs.size + end + def test_get_ids assert_equal [posts(:welcome).id, posts(:authorless).id].sort, people(:michael).post_ids.sort end -- cgit v1.2.3 From 276ea48de96a0c4242139ec9323eefb6f254c2a1 Mon Sep 17 00:00:00 2001 From: Yaroslav Markin Date: Sun, 21 Dec 2008 11:35:50 +0000 Subject: Remove dead commented out code [#1467 state:resolved] Signed-off-by: Frederick Cheung --- activerecord/lib/active_record/validations.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index 617b3f440f..6a9690ba85 100644 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -203,7 +203,6 @@ module ActiveRecord if attr == "base" full_messages << message else - #key = :"activerecord.att.#{@base.class.name.underscore.to_sym}.#{attr}" attr_name = @base.class.human_attribute_name(attr) full_messages << attr_name + I18n.t('activerecord.errors.format.separator', :default => ' ') + message end -- cgit v1.2.3 From 6f4b2469fb19bb01fa0f53192eb49f8f2d95db1b Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Sun, 21 Dec 2008 12:37:29 +0000 Subject: Use explicit order to stop test failing randomly --- activerecord/test/cases/associations/eager_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activerecord') diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 42063d18a3..a2d0efab92 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -729,12 +729,12 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_equal authors(:david), assert_no_queries { posts[0].author} posts = assert_queries(2) do - Post.find(:all, :include => :author, :joins => {:taggings => :tag}, :conditions => "tags.name = 'General'") + Post.find(:all, :include => :author, :joins => {:taggings => :tag}, :conditions => "tags.name = 'General'", :order => 'posts.id') end assert_equal posts(:welcome, :thinking), posts posts = assert_queries(2) do - Post.find(:all, :include => :author, :joins => {:taggings => {:tag => :taggings}}, :conditions => "taggings_tags.super_tag_id=2") + Post.find(:all, :include => :author, :joins => {:taggings => {:tag => :taggings}}, :conditions => "taggings_tags.super_tag_id=2", :order => 'posts.id') end assert_equal posts(:welcome, :thinking), posts -- cgit v1.2.3 From b17b9371c6a26484eb1984d45acffcdcd91b1ae1 Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Sun, 21 Dec 2008 15:38:40 +0000 Subject: Fix configure_dependency_for_has_many not quoting conditions properly [#1461 state:resolved] --- activerecord/lib/active_record/associations.rb | 6 +++--- .../test/cases/associations/has_many_associations_test.rb | 13 +++++++++++++ activerecord/test/models/company.rb | 1 + 3 files changed, 17 insertions(+), 3 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 07bc50c886..5a60b13fd8 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1453,7 +1453,7 @@ module ActiveRecord dependent_conditions << sanitize_sql(reflection.options[:conditions]) if reflection.options[:conditions] dependent_conditions << extra_conditions if extra_conditions dependent_conditions = dependent_conditions.collect {|where| "(#{where})" }.join(" AND ") - + dependent_conditions = dependent_conditions.gsub('@', '\@') case reflection.options[:dependent] when :destroy method_name = "has_many_dependent_destroy_for_#{reflection.name}".to_sym @@ -1467,7 +1467,7 @@ module ActiveRecord delete_all_has_many_dependencies(record, "#{reflection.name}", #{reflection.class_name}, - "#{dependent_conditions}") + %@#{dependent_conditions}@) end } when :nullify @@ -1477,7 +1477,7 @@ module ActiveRecord "#{reflection.name}", #{reflection.class_name}, "#{reflection.primary_key_name}", - "#{dependent_conditions}") + %@#{dependent_conditions}@) end } else diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index 816ceb6855..20b9acda44 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -665,6 +665,19 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal 1, Client.find_all_by_client_of(firm.id).size end + def test_dependent_association_respects_optional_hash_conditions_on_delete + firm = companies(:odegy) + Client.create(:client_of => firm.id, :name => "BigShot Inc.") + Client.create(:client_of => firm.id, :name => "SmallTime Inc.") + # only one of two clients is included in the association due to the :conditions key + assert_equal 2, Client.find_all_by_client_of(firm.id).size + assert_equal 1, firm.dependent_sanitized_conditional_clients_of_firm.size + firm.destroy + # only the correctly associated client should have been deleted + assert_equal 1, Client.find_all_by_client_of(firm.id).size + end + + def test_creation_respects_hash_condition ms_client = companies(:first_firm).clients_like_ms_with_hash_conditions.build diff --git a/activerecord/test/models/company.rb b/activerecord/test/models/company.rb index 0e3fafa37c..3b27a9e272 100644 --- a/activerecord/test/models/company.rb +++ b/activerecord/test/models/company.rb @@ -80,6 +80,7 @@ class ExclusivelyDependentFirm < Company has_one :account, :foreign_key => "firm_id", :dependent => :delete has_many :dependent_sanitized_conditional_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all, :conditions => "name = 'BigShot Inc.'" has_many :dependent_conditional_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all, :conditions => ["name = ?", 'BigShot Inc.'] + has_many :dependent_hash_conditional_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all, :conditions => {:name => 'BigShot Inc.'} end class Client < Company -- cgit v1.2.3 From f7bd0beb67c5d9d50e37aa596605b91e61197fbe Mon Sep 17 00:00:00 2001 From: Daniel Luz Date: Sun, 21 Dec 2008 22:38:12 +0000 Subject: Ensure Model#last doesn't affects order for another finders inside the same scope [#1499 state:resolved] Signed-off-by: Pratik Naik --- activerecord/lib/active_record/base.rb | 11 ++++++++--- activerecord/test/cases/method_scoping_test.rb | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index aa6013583d..9db0366c46 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1494,11 +1494,16 @@ module ActiveRecord #:nodoc: end if scoped?(:find, :order) - scoped_order = reverse_sql_order(scope(:find, :order)) - scoped_methods.select { |s| s[:find].update(:order => scoped_order) } + scope = scope(:find) + original_scoped_order = scope[:order] + scope[:order] = reverse_sql_order(original_scoped_order) end - find_initial(options.merge({ :order => order })) + begin + find_initial(options.merge({ :order => order })) + ensure + scope[:order] = original_scoped_order if original_scoped_order + end end def reverse_sql_order(order_query) diff --git a/activerecord/test/cases/method_scoping_test.rb b/activerecord/test/cases/method_scoping_test.rb index 6372b4f6aa..80a06116ad 100644 --- a/activerecord/test/cases/method_scoping_test.rb +++ b/activerecord/test/cases/method_scoping_test.rb @@ -27,6 +27,24 @@ class MethodScopingTest < ActiveRecord::TestCase end end + def test_scoped_find_last + highest_salary = Developer.find(:first, :order => "salary DESC") + + Developer.with_scope(:find => { :order => "salary" }) do + assert_equal highest_salary, Developer.last + end + end + + def test_scoped_find_last_preserves_scope + lowest_salary = Developer.find(:first, :order => "salary ASC") + highest_salary = Developer.find(:first, :order => "salary DESC") + + Developer.with_scope(:find => { :order => "salary" }) do + assert_equal highest_salary, Developer.last + assert_equal lowest_salary, Developer.first + end + end + def test_scoped_find_combines_conditions Developer.with_scope(:find => { :conditions => "salary = 9000" }) do assert_equal developers(:poor_jamis), Developer.find(:first, :conditions => "name = 'Jamis'") -- cgit v1.2.3 From 63aac338332a06d3c9e28dde7954679703ec7620 Mon Sep 17 00:00:00 2001 From: Luis Hurtado Date: Mon, 22 Dec 2008 15:18:43 +0000 Subject: Ensure of Model#create support custom updated_at and updated_on attributes [#1612 state:resolved] Signed-off-by: Pratik Naik --- activerecord/lib/active_record/timestamp.rb | 4 ++-- activerecord/test/cases/base_test.rb | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/timestamp.rb b/activerecord/lib/active_record/timestamp.rb index a9e0efa6fe..8dbe80a01a 100644 --- a/activerecord/lib/active_record/timestamp.rb +++ b/activerecord/lib/active_record/timestamp.rb @@ -23,8 +23,8 @@ module ActiveRecord write_attribute('created_at', t) if respond_to?(:created_at) && created_at.nil? write_attribute('created_on', t) if respond_to?(:created_on) && created_on.nil? - write_attribute('updated_at', t) if respond_to?(:updated_at) - write_attribute('updated_on', t) if respond_to?(:updated_on) + write_attribute('updated_at', t) if respond_to?(:updated_at) && updated_at.nil? + write_attribute('updated_on', t) if respond_to?(:updated_on) && updated_on.nil? end create_without_timestamps end diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 5f54931d00..ce77ba4dbf 100755 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -16,6 +16,7 @@ require 'models/post' require 'models/comment' require 'models/minimalistic' require 'models/warehouse_thing' +require 'models/parrot' require 'rexml/document' class Category < ActiveRecord::Base; end @@ -2071,6 +2072,15 @@ class BasicsTest < ActiveRecord::TestCase ActiveRecord::Base.logger = original_logger end + def test_create_with_custom_timestamps + custom_datetime = 1.hour.ago.beginning_of_day + + %w(created_at created_on updated_at updated_on).each do |attribute| + parrot = LiveParrot.create(:name => "colombian", attribute => custom_datetime) + assert_equal custom_datetime, parrot[attribute] + end + end + private def with_kcode(kcode) if RUBY_VERSION < '1.9' -- cgit v1.2.3 From aa002c0e86afdc83693f14667a710107843f0fbd Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 22 Dec 2008 11:31:18 -0600 Subject: ActiveRecord::QueryCache middleware --- activerecord/lib/active_record/base.rb | 2 +- activerecord/lib/active_record/query_cache.rb | 38 ++++++++++++++++++--------- 2 files changed, 26 insertions(+), 14 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 9db0366c46..9746a46d47 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -3015,7 +3015,7 @@ module ActiveRecord #:nodoc: end Base.class_eval do - extend QueryCache + extend QueryCache::ClassMethods include Validations include Locking::Optimistic, Locking::Pessimistic include AttributeMethods diff --git a/activerecord/lib/active_record/query_cache.rb b/activerecord/lib/active_record/query_cache.rb index a8af89fcb9..eb92bc2545 100644 --- a/activerecord/lib/active_record/query_cache.rb +++ b/activerecord/lib/active_record/query_cache.rb @@ -1,20 +1,32 @@ module ActiveRecord - module QueryCache - # Enable the query cache within the block if Active Record is configured. - def cache(&block) - if ActiveRecord::Base.configurations.blank? - yield - else - connection.cache(&block) + class QueryCache + module ClassMethods + # Enable the query cache within the block if Active Record is configured. + def cache(&block) + if ActiveRecord::Base.configurations.blank? + yield + else + connection.cache(&block) + end end + + # Disable the query cache within the block if Active Record is configured. + def uncached(&block) + if ActiveRecord::Base.configurations.blank? + yield + else + connection.uncached(&block) + end + end + end + + def initialize(app) + @app = app end - # Disable the query cache within the block if Active Record is configured. - def uncached(&block) - if ActiveRecord::Base.configurations.blank? - yield - else - connection.uncached(&block) + def call(env) + ActiveRecord::Base.cache do + @app.call(env) end end end -- cgit v1.2.3 From eb457ceee13779ade67e1bdebd2919d476148277 Mon Sep 17 00:00:00 2001 From: Pivotal Labs Date: Wed, 24 Dec 2008 14:57:09 -0800 Subject: Association preloading no longer stops if it hits a nil object [#1630 state:resolved] Signed-off-by: Frederick Cheung --- activerecord/lib/active_record/association_preload.rb | 4 ++-- .../test/cases/associations/cascaded_eager_loading_test.rb | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb index 7b1b2d9ad9..0bcf50c167 100644 --- a/activerecord/lib/active_record/association_preload.rb +++ b/activerecord/lib/active_record/association_preload.rb @@ -94,8 +94,8 @@ module ActiveRecord raise "parent must be an association name" unless parent.is_a?(String) || parent.is_a?(Symbol) preload_associations(records, parent, preload_options) reflection = reflections[parent] - parents = records.map {|record| record.send(reflection.name)}.flatten - unless parents.empty? || parents.first.nil? + parents = records.map {|record| record.send(reflection.name)}.flatten.compact + unless parents.empty? parents.first.class.preload_associations(parents, child) end end diff --git a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb index 8c9ae8a031..45e74ea024 100644 --- a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb +++ b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb @@ -104,6 +104,14 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase authors.first.posts.first.special_comments.first.post.very_special_comment end end + + def test_eager_association_loading_where_first_level_returns_nil + authors = Author.find(:all, :include => {:post_about_thinking => :comments}, :order => 'authors.id DESC') + assert_equal [authors(:mary), authors(:david)], authors + assert_no_queries do + authors[1].post_about_thinking.comments.first + end + end end require 'models/vertex' -- cgit v1.2.3 From 5cebe69e74d411c3c9e5f6ab9d4b2b16ee36177c Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Fri, 19 Dec 2008 01:02:21 +0000 Subject: Preload uses exclusive scope [#643 state:resolved] With self referential associations, the scope for the the top level should not affect fetching of associations, for example when doing Person.male.find :all, :include => :friends we should load all of the friends for each male, not just the male friends. --- .../lib/active_record/association_preload.rb | 31 +++++++++++++--------- activerecord/test/cases/associations/eager_test.rb | 15 +++++++++++ activerecord/test/fixtures/people.yml | 11 +++++++- activerecord/test/models/person.rb | 6 +++++ activerecord/test/schema/schema.rb | 6 +++-- 5 files changed, 53 insertions(+), 16 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb index 0bcf50c167..9d0bf3a308 100644 --- a/activerecord/lib/active_record/association_preload.rb +++ b/activerecord/lib/active_record/association_preload.rb @@ -43,7 +43,7 @@ module ActiveRecord # loading in a more high-level (application developer-friendly) manner. module ClassMethods protected - + # Eager loads the named associations for the given ActiveRecord record(s). # # In this description, 'association name' shall refer to the name passed @@ -113,7 +113,7 @@ module ActiveRecord # unnecessarily 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. @@ -128,7 +128,7 @@ module ActiveRecord association_proxy.target.push(*[associated_record].flatten) end end - + def add_preloaded_record_to_collection(parent_records, reflection_name, associated_record) parent_records.each do |parent_record| parent_record.send("set_#{reflection_name}_target", associated_record) @@ -183,18 +183,19 @@ module ActiveRecord conditions = "t0.#{reflection.primary_key_name} #{in_or_equals_for_ids(ids)}" conditions << append_conditions(reflection, preload_options) - associated_records = reflection.klass.find(:all, :conditions => [conditions, ids], - :include => options[:include], - :joins => "INNER JOIN #{connection.quote_table_name options[:join_table]} t0 ON #{reflection.klass.quoted_table_name}.#{reflection.klass.primary_key} = t0.#{reflection.association_foreign_key}", - :select => "#{options[:select] || table_name+'.*'}, t0.#{reflection.primary_key_name} as the_parent_record_id", - :order => options[:order]) - + associated_records = reflection.klass.with_exclusive_scope do + reflection.klass.find(:all, :conditions => [conditions, ids], + :include => options[:include], + :joins => "INNER JOIN #{connection.quote_table_name options[:join_table]} t0 ON #{reflection.klass.quoted_table_name}.#{reflection.klass.primary_key} = t0.#{reflection.association_foreign_key}", + :select => "#{options[:select] || table_name+'.*'}, t0.#{reflection.primary_key_name} as the_parent_record_id", + :order => options[:order]) + end set_association_collection_records(id_to_record_map, reflection.name, associated_records, 'the_parent_record_id') end def preload_has_one_association(records, reflection, preload_options={}) return if records.first.send("loaded_#{reflection.name}?") - id_to_record_map, ids = construct_id_map(records) + id_to_record_map, ids = construct_id_map(records) options = reflection.options records.each {|record| record.send("set_#{reflection.name}_target", nil)} if options[:through] @@ -248,7 +249,7 @@ module ActiveRecord reflection.primary_key_name) end end - + def preload_through_records(records, reflection, through_association) through_reflection = reflections[through_association] through_primary_key = through_reflection.primary_key_name @@ -333,11 +334,13 @@ module ActiveRecord end conditions = "#{table_name}.#{connection.quote_column_name(primary_key)} #{in_or_equals_for_ids(ids)}" conditions << append_conditions(reflection, preload_options) - associated_records = klass.find(:all, :conditions => [conditions, ids], + associated_records = klass.with_exclusive_scope do + klass.find(:all, :conditions => [conditions, ids], :include => options[:include], :select => options[:select], :joins => options[:joins], :order => options[:order]) + end set_association_single_records(id_map, reflection.name, associated_records, primary_key) end end @@ -355,13 +358,15 @@ module ActiveRecord conditions << append_conditions(reflection, preload_options) - reflection.klass.find(:all, + reflection.klass.with_exclusive_scope do + reflection.klass.find(:all, :select => (preload_options[:select] || options[:select] || "#{table_name}.*"), :include => preload_options[:include] || options[:include], :conditions => [conditions, ids], :joins => options[:joins], :group => preload_options[:group] || options[:group], :order => preload_options[:order] || options[:order]) + end end diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index a2d0efab92..afbd9fddf9 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -771,4 +771,19 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_equal author_addresses(:david_address), authors[0].author_address end + def test_preload_belongs_to_uses_exclusive_scope + people = Person.males.find(:all, :include => :primary_contact) + assert_not_equal people.length, 0 + people.each do |person| + assert_no_queries {assert_not_nil person.primary_contact} + assert_equal Person.find(person.id).primary_contact, person.primary_contact + end + end + + def test_preload_has_many_uses_exclusive_scope + people = Person.males.find :all, :include => :agents + people.each do |person| + assert_equal Person.find(person.id).agents, person.agents + end + end end diff --git a/activerecord/test/fixtures/people.yml b/activerecord/test/fixtures/people.yml index d5a69e561d..3babb1fe59 100644 --- a/activerecord/test/fixtures/people.yml +++ b/activerecord/test/fixtures/people.yml @@ -1,6 +1,15 @@ michael: id: 1 first_name: Michael + primary_contact_id: 2 + gender: M david: id: 2 - first_name: David \ No newline at end of file + first_name: David + primary_contact_id: 3 + gender: M +susan: + id: 3 + first_name: Susan + primary_contact_id: 2 + gender: F \ No newline at end of file diff --git a/activerecord/test/models/person.rb b/activerecord/test/models/person.rb index 430d0b38f7..ec2f684a6e 100644 --- a/activerecord/test/models/person.rb +++ b/activerecord/test/models/person.rb @@ -7,4 +7,10 @@ class Person < ActiveRecord::Base 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' + + belongs_to :primary_contact, :class_name => 'Person' + has_many :agents, :class_name => 'Person', :foreign_key => 'primary_contact_id' + + named_scope :males, :conditions => { :gender => 'M' } + named_scope :females, :conditions => { :gender => 'F' } end diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index fbacc692b4..8199cb8fc7 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -298,8 +298,10 @@ ActiveRecord::Schema.define do end create_table :people, :force => true do |t| - t.string :first_name, :null => false - t.integer :lock_version, :null => false, :default => 0 + t.string :first_name, :null => false + t.references :primary_contact + t.string :gender, :limit => 1 + t.integer :lock_version, :null => false, :default => 0 end create_table :pets, :primary_key => :pet_id ,:force => true do |t| -- cgit v1.2.3 From 7db1704068b86fb2212388b14b4963526bacfa5d Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Fri, 26 Dec 2008 22:53:07 +0000 Subject: Fix :include of has_many associations with :primary_key option --- activerecord/lib/active_record/association_preload.rb | 2 +- activerecord/lib/active_record/associations.rb | 2 +- activerecord/test/cases/associations/eager_test.rb | 17 +++++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb index 9d0bf3a308..195d2fb4f8 100644 --- a/activerecord/lib/active_record/association_preload.rb +++ b/activerecord/lib/active_record/association_preload.rb @@ -229,7 +229,7 @@ module ActiveRecord options = reflection.options primary_key_name = reflection.through_reflection_primary_key_name - id_to_record_map, ids = construct_id_map(records, primary_key_name) + id_to_record_map, ids = construct_id_map(records, primary_key_name || reflection.options[:primary_key]) records.each {|record| record.send(reflection.name).loaded} if options[:through] diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 5a60b13fd8..237e5c0e9d 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -2171,7 +2171,7 @@ module ActiveRecord aliased_table_name, foreign_key, parent.aliased_table_name, - parent.primary_key + reflection.options[:primary_key] || parent.primary_key ] end when :belongs_to diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index afbd9fddf9..ff3d6ece05 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -786,4 +786,21 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_equal Person.find(person.id).agents, person.agents end end + + def test_preload_has_many_using_primary_key + expected = Firm.find(:first).clients_using_primary_key.to_a + firm = Firm.find :first, :include => :clients_using_primary_key + assert_no_queries do + assert_equal expected, firm.clients_using_primary_key + end + end + + def test_include_has_many_using_primary_key + expected = Firm.find(1).clients_using_primary_key.sort_by &:name + firm = Firm.find 1, :include => :clients_using_primary_key, :order => 'clients_using_primary_keys_companies.name' + assert_no_queries do + assert_equal expected, firm.clients_using_primary_key + end + end + end -- cgit v1.2.3 From f9cab0e503a4721c9d0369f89bb85c6e658f778c Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Fri, 26 Dec 2008 23:26:37 +0000 Subject: Fix :include of has_one with :primary_key option --- activerecord/lib/active_record/association_preload.rb | 2 +- activerecord/test/cases/associations/eager_test.rb | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb index 195d2fb4f8..e4ab69aa1b 100644 --- a/activerecord/lib/active_record/association_preload.rb +++ b/activerecord/lib/active_record/association_preload.rb @@ -195,7 +195,7 @@ module ActiveRecord def preload_has_one_association(records, reflection, preload_options={}) return if records.first.send("loaded_#{reflection.name}?") - id_to_record_map, ids = construct_id_map(records) + id_to_record_map, ids = construct_id_map(records, reflection.options[:primary_key]) options = reflection.options records.each {|record| record.send("set_#{reflection.name}_target", nil)} if options[:through] diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index ff3d6ece05..14099d4176 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -803,4 +803,20 @@ class EagerAssociationTest < ActiveRecord::TestCase end end + def test_preload_has_one_using_primary_key + expected = Firm.find(:first).account_using_primary_key + firm = Firm.find :first, :include => :account_using_primary_key + assert_no_queries do + assert_equal expected, firm.account_using_primary_key + end + end + + def test_include_has_one_using_primary_key + expected = Firm.find(1).account_using_primary_key + firm = Firm.find(:all, :include => :account_using_primary_key, :order => 'accounts.id').detect {|f| f.id == 1} + assert_no_queries do + assert_equal expected, firm.account_using_primary_key + end + end + end -- cgit v1.2.3 From 21efba464afa2ae6e5dfd938ac8a3ce446faf7e7 Mon Sep 17 00:00:00 2001 From: Roman Shterenzon Date: Sat, 27 Dec 2008 01:10:29 +0000 Subject: Fix HasManyAssociation#create ignoring the :primary_key option [#1633 state:resolved] Signed-off-by: Frederick Cheung --- activerecord/lib/active_record/associations/association_proxy.rb | 5 ++++- activerecord/test/cases/associations/has_many_associations_test.rb | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb index 59f1d3b867..676c4ace61 100644 --- a/activerecord/lib/active_record/associations/association_proxy.rb +++ b/activerecord/lib/active_record/associations/association_proxy.rb @@ -180,7 +180,10 @@ module ActiveRecord record["#{@reflection.options[:as]}_id"] = @owner.id unless @owner.new_record? record["#{@reflection.options[:as]}_type"] = @owner.class.base_class.name.to_s else - record[@reflection.primary_key_name] = @owner.id unless @owner.new_record? + unless @owner.new_record? + primary_key = @reflection.options[:primary_key] || :id + record[@reflection.primary_key_name] = @owner.send(primary_key) + end end end diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index 20b9acda44..a5ae5cd8ec 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -1115,5 +1115,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert !client_association.respond_to?(:private_method) assert client_association.respond_to?(:private_method, true) end + + def test_creating_using_primary_key + firm = Firm.find(:first) + client = firm.clients_using_primary_key.create!(:name => 'test') + assert_equal firm.name, client.firm_name + end end -- cgit v1.2.3 From 6e98adfc8e19a39fa45d4acd94145d318d151964 Mon Sep 17 00:00:00 2001 From: Yaroslav Markin Date: Sat, 27 Dec 2008 16:26:13 +0300 Subject: ActiveRecord::Base#new_record? now returns false for existing records (was nil) [#1219 state:committed] Signed-off-by: David Heinemeier Hansson --- activerecord/CHANGELOG | 2 ++ activerecord/lib/active_record/base.rb | 4 ++-- activerecord/test/cases/base_test.rb | 5 +++++ 3 files changed, 9 insertions(+), 2 deletions(-) (limited to 'activerecord') diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index d057ddfcd0..9cfd16cc0d 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,7 @@ *2.3.0/3.0* +* Fixed that ActiveRecord::Base#new_record? should return false (not nil) for existing records #1219 [Yaroslav Markin] + * I18n the word separator for error messages. Introduces the activerecord.errors.format.separator translation key. #1294 [Akira Matsuda] * Add :having as a key to find and the relevant associations. [Emilio Tagua] diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 9746a46d47..80c109aea7 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -2406,9 +2406,9 @@ module ActiveRecord #:nodoc: write_attribute(self.class.primary_key, value) end - # Returns true if this object hasn't been saved yet -- that is, a record for the object doesn't exist yet. + # Returns true if this object hasn't been saved yet -- that is, a record for the object doesn't exist yet; otherwise, returns false. def new_record? - defined?(@new_record) && @new_record + (defined?(@new_record) && @new_record) || false end # :call-seq: diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index ce77ba4dbf..0f03dae829 100755 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1198,6 +1198,11 @@ class BasicsTest < ActiveRecord::TestCase assert b_true.value? end + def test_new_record_returns_boolean + assert_equal Topic.new.new_record?, true + assert_equal Topic.find(1).new_record?, false + end + def test_clone topic = Topic.find(1) cloned_topic = nil -- cgit v1.2.3 From afdec83ed543e904b495d3225b6401101ea7ba6c Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Sat, 27 Dec 2008 14:16:17 +0000 Subject: Fix to_sentence being used with options removed by 273c77 --- activerecord/lib/active_record/associations.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 237e5c0e9d..eba10b505e 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -22,7 +22,7 @@ module ActiveRecord through_reflection = reflection.through_reflection source_reflection_names = reflection.source_reflection_names source_associations = reflection.through_reflection.klass.reflect_on_all_associations.collect { |a| a.name.inspect } - super("Could not find the source association(s) #{source_reflection_names.collect(&:inspect).to_sentence :connector => 'or'} in model #{through_reflection.klass}. Try 'has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}, :source => '. Is it one of #{source_associations.to_sentence :connector => 'or'}?") + super("Could not find the source association(s) #{source_reflection_names.collect(&:inspect).to_sentence :two_words_connector => ' or ', :last_word_connector => ', or '} in model #{through_reflection.klass}. Try 'has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}, :source => '. Is it one of #{source_associations.to_sentence :two_words_connector => ' or ', :last_word_connector => ', or '}?") end end -- cgit v1.2.3 From 28347d889bb4304e681bf885fea734067fdd8ff6 Mon Sep 17 00:00:00 2001 From: Yaroslav Markin Date: Sat, 27 Dec 2008 17:02:07 +0300 Subject: Refactor ActiveRecord::Base#new_record? [#1647 state:committed] Signed-off-by: David Heinemeier Hansson --- activerecord/lib/active_record/base.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 80c109aea7..e5e94555eb 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -2408,7 +2408,7 @@ module ActiveRecord #:nodoc: # Returns true if this object hasn't been saved yet -- that is, a record for the object doesn't exist yet; otherwise, returns false. def new_record? - (defined?(@new_record) && @new_record) || false + @new_record || false end # :call-seq: -- cgit v1.2.3 From a2270ef2594b97891994848138614657363f2806 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sun, 28 Dec 2008 19:48:05 +0000 Subject: Inline code comments for class_eval/module_eval [#1657 state:resolved] Signed-off-by: Pratik Naik --- activerecord/lib/active_record/associations.rb | 36 ++++++++-------- activerecord/lib/active_record/base.rb | 48 +++++++++++++++++++++- .../connection_adapters/abstract/query_cache.rb | 12 +++--- .../abstract/schema_definitions.rb | 48 +++++++++++----------- .../connection_adapters/mysql_adapter.rb | 24 ++++++----- .../connection_adapters/postgresql_adapter.rb | 14 +++---- activerecord/lib/active_record/dirty.rb | 2 +- 7 files changed, 116 insertions(+), 68 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 5a60b13fd8..c154a5087c 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1216,11 +1216,11 @@ module ActiveRecord # callbacks will be executed after the association is wiped out. old_method = "destroy_without_habtm_shim_for_#{reflection.name}" class_eval <<-end_eval unless method_defined?(old_method) - alias_method :#{old_method}, :destroy_without_callbacks - def destroy_without_callbacks - #{reflection.name}.clear - #{old_method} - end + alias_method :#{old_method}, :destroy_without_callbacks # alias_method :destroy_without_habtm_shim_for_posts, :destroy_without_callbacks + def destroy_without_callbacks # def destroy_without_callbacks + #{reflection.name}.clear # posts.clear + #{old_method} # destroy_without_habtm_shim_for_posts + end # end end_eval add_association_callbacks(reflection.name, options) @@ -1463,22 +1463,22 @@ module ActiveRecord before_destroy method_name when :delete_all module_eval %Q{ - before_destroy do |record| - delete_all_has_many_dependencies(record, - "#{reflection.name}", - #{reflection.class_name}, - %@#{dependent_conditions}@) - end + before_destroy do |record| # before_destroy do |record| + delete_all_has_many_dependencies(record, # delete_all_has_many_dependencies(record, + "#{reflection.name}", # "posts", + #{reflection.class_name}, # Post, + %@#{dependent_conditions}@) # %@...@) # this is a string literal like %(...) + end # end } when :nullify module_eval %Q{ - before_destroy do |record| - nullify_has_many_dependencies(record, - "#{reflection.name}", - #{reflection.class_name}, - "#{reflection.primary_key_name}", - %@#{dependent_conditions}@) - end + before_destroy do |record| # before_destroy do |record| + nullify_has_many_dependencies(record, # nullify_has_many_dependencies(record, + "#{reflection.name}", # "posts", + #{reflection.class_name}, # Post, + "#{reflection.primary_key_name}", # "user_id", + %@#{dependent_conditions}@) # %@...@) # this is a string literal like %(...) + end # end } else raise ArgumentError, "The :dependent option expects either :destroy, :delete_all, or :nullify (#{reflection.options[:dependent].inspect})" diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index e5e94555eb..4c9ad24ea3 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1818,10 +1818,31 @@ module ActiveRecord #:nodoc: if match.finder? finder = match.finder bang = match.bang? + # def self.find_by_login_and_activated(*args) + # options = args.extract_options! + # attributes = construct_attributes_from_arguments( + # [:login,:activated], + # args + # ) + # finder_options = { :conditions => attributes } + # validate_find_options(options) + # set_readonly_option!(options) + # + # if options[:conditions] + # with_scope(:find => finder_options) do + # find(:first, options) + # end + # else + # find(:first, options.merge(finder_options)) + # end + # end self.class_eval %{ def self.#{method_id}(*args) options = args.extract_options! - attributes = construct_attributes_from_arguments([:#{attribute_names.join(',:')}], args) + attributes = construct_attributes_from_arguments( + [:#{attribute_names.join(',:')}], + args + ) finder_options = { :conditions => attributes } validate_find_options(options) set_readonly_option!(options) @@ -1839,6 +1860,31 @@ module ActiveRecord #:nodoc: send(method_id, *arguments) elsif match.instantiator? instantiator = match.instantiator + # def self.find_or_create_by_user_id(*args) + # guard_protected_attributes = false + # + # if args[0].is_a?(Hash) + # guard_protected_attributes = true + # attributes = args[0].with_indifferent_access + # find_attributes = attributes.slice(*[:user_id]) + # else + # find_attributes = attributes = construct_attributes_from_arguments([:user_id], args) + # end + # + # options = { :conditions => find_attributes } + # set_readonly_option!(options) + # + # record = find(:first, options) + # + # if record.nil? + # record = self.new { |r| r.send(:attributes=, attributes, guard_protected_attributes) } + # yield(record) if block_given? + # record.save + # record + # else + # record + # end + # end self.class_eval %{ def self.#{method_id}(*args) guard_protected_attributes = false diff --git a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb index 950bd72101..00c71090f3 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb @@ -14,12 +14,12 @@ module ActiveRecord def dirties_query_cache(base, *method_names) method_names.each do |method_name| base.class_eval <<-end_code, __FILE__, __LINE__ - def #{method_name}_with_query_dirty(*args) - clear_query_cache if @query_cache_enabled - #{method_name}_without_query_dirty(*args) - end - - alias_method_chain :#{method_name}, :query_dirty + def #{method_name}_with_query_dirty(*args) # def update_with_query_dirty(*args) + clear_query_cache if @query_cache_enabled # clear_query_cache if @query_cache_enabled + #{method_name}_without_query_dirty(*args) # update_without_query_dirty(*args) + end # end + # + alias_method_chain :#{method_name}, :query_dirty # alias_method_chain :update, :query_dirty end_code end end diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index fe9cbcf024..273f823e7f 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -476,12 +476,12 @@ module ActiveRecord %w( string text integer float decimal datetime timestamp time date binary boolean ).each do |column_type| class_eval <<-EOV - def #{column_type}(*args) - options = args.extract_options! - column_names = args - - column_names.each { |name| column(name, '#{column_type}', options) } - end + def #{column_type}(*args) # def string(*args) + options = args.extract_options! # options = args.extract_options! + column_names = args # column_names = args + # + column_names.each { |name| column(name, '#{column_type}', options) } # column_names.each { |name| column(name, 'string', options) } + end # end EOV end @@ -676,24 +676,24 @@ module ActiveRecord # t.string(:goat, :sheep) %w( string text integer float decimal datetime timestamp time date binary boolean ).each do |column_type| class_eval <<-EOV - def #{column_type}(*args) - options = args.extract_options! - column_names = args - - column_names.each do |name| - column = ColumnDefinition.new(@base, name, '#{column_type}') - if options[:limit] - column.limit = options[:limit] - elsif native['#{column_type}'.to_sym].is_a?(Hash) - column.limit = native['#{column_type}'.to_sym][:limit] - end - column.precision = options[:precision] - column.scale = options[:scale] - column.default = options[:default] - column.null = options[:null] - @base.add_column(@table_name, name, column.sql_type, options) - end - end + def #{column_type}(*args) # def string(*args) + options = args.extract_options! # options = args.extract_options! + column_names = args # column_names = args + # + column_names.each do |name| # column_names.each do |name| + column = ColumnDefinition.new(@base, name, '#{column_type}') # column = ColumnDefinition.new(@base, name, 'string') + if options[:limit] # if options[:limit] + column.limit = options[:limit] # column.limit = options[:limit] + elsif native['#{column_type}'.to_sym].is_a?(Hash) # elsif native['string'.to_sym].is_a?(Hash) + column.limit = native['#{column_type}'.to_sym][:limit] # column.limit = native['string'.to_sym][:limit] + end # end + column.precision = options[:precision] # column.precision = options[:precision] + column.scale = options[:scale] # column.scale = options[:scale] + column.default = options[:default] # column.default = options[:default] + column.null = options[:null] # column.null = options[:null] + @base.add_column(@table_name, name, column.sql_type, options) # @base.add_column(@table_name, name, column.sql_type, options) + end # end + end # end EOV end diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb index 46d4b6c89c..60729c63db 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb @@ -13,23 +13,25 @@ module MysqlCompat #:nodoc: # C driver >= 2.7 returns null values in each_hash if Mysql.const_defined?(:VERSION) && (Mysql::VERSION.is_a?(String) || Mysql::VERSION >= 20700) target.class_eval <<-'end_eval' - def all_hashes - rows = [] - each_hash { |row| rows << row } - rows - end + def all_hashes # def all_hashes + rows = [] # rows = [] + each_hash { |row| rows << row } # each_hash { |row| rows << row } + rows # rows + end # end end_eval # adapters before 2.7 don't have a version constant # and don't return null values in each_hash else target.class_eval <<-'end_eval' - def all_hashes - rows = [] - all_fields = fetch_fields.inject({}) { |fields, f| fields[f.name] = nil; fields } - each_hash { |row| rows << all_fields.dup.update(row) } - rows - end + def all_hashes # def all_hashes + rows = [] # rows = [] + all_fields = fetch_fields.inject({}) { |fields, f| # all_fields = fetch_fields.inject({}) { |fields, f| + fields[f.name] = nil; fields # fields[f.name] = nil; fields + } # } + each_hash { |row| rows << all_fields.dup.update(row) } # each_hash { |row| rows << all_fields.dup.update(row) } + rows # rows + end # end end_eval end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 60ec01b95e..6685cb8663 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -950,13 +950,13 @@ module ActiveRecord # should know about this but can't detect it there, so deal with it here. money_precision = (postgresql_version >= 80300) ? 19 : 10 PostgreSQLColumn.module_eval(<<-end_eval) - def extract_precision(sql_type) - if sql_type =~ /^money$/ - #{money_precision} - else - super - end - end + def extract_precision(sql_type) # def extract_precision(sql_type) + if sql_type =~ /^money$/ # if sql_type =~ /^money$/ + #{money_precision} # 19 + else # else + super # super + end # end + end # end end_eval configure_connection diff --git a/activerecord/lib/active_record/dirty.rb b/activerecord/lib/active_record/dirty.rb index a1760875ba..4c899f58e5 100644 --- a/activerecord/lib/active_record/dirty.rb +++ b/activerecord/lib/active_record/dirty.rb @@ -174,7 +174,7 @@ module ActiveRecord alias_attribute_without_dirty(new_name, old_name) DIRTY_SUFFIXES.each do |suffix| module_eval <<-STR, __FILE__, __LINE__+1 - def #{new_name}#{suffix}; self.#{old_name}#{suffix}; end + def #{new_name}#{suffix}; self.#{old_name}#{suffix}; end # def subject_changed?; self.title_changed?; end STR end end -- cgit v1.2.3 From 66ee5890c5f21995b7fe0c486547f1287afe2b55 Mon Sep 17 00:00:00 2001 From: Yaroslav Markin Date: Sun, 28 Dec 2008 22:25:55 +0300 Subject: Introduce dynamic scopes for ActiveRecord: you can now use class methods like scoped_by_user_name(user_name) and scoped_by_user_name_and_password(user_name, password) that will use the scoped method with attributes you supply. [#1648 state:committed] Signed-off-by: David Heinemeier Hansson --- activerecord/CHANGELOG | 2 ++ activerecord/lib/active_record.rb | 1 + activerecord/lib/active_record/base.rb | 25 +++++++++++++++++++++- .../lib/active_record/dynamic_scope_match.rb | 25 ++++++++++++++++++++++ activerecord/test/cases/named_scope_test.rb | 20 +++++++++++++++++ 5 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 activerecord/lib/active_record/dynamic_scope_match.rb (limited to 'activerecord') diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 9cfd16cc0d..c750f486f9 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,7 @@ *2.3.0/3.0* +* Added dynamic scopes ala dynamic finders #1648 [Yaroslav Markin] + * Fixed that ActiveRecord::Base#new_record? should return false (not nil) for existing records #1219 [Yaroslav Markin] * I18n the word separator for error messages. Introduces the activerecord.errors.format.separator translation key. #1294 [Akira Matsuda] diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index c428366a04..390c005785 100644 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -51,6 +51,7 @@ module ActiveRecord autoload :Callbacks, 'active_record/callbacks' autoload :Dirty, 'active_record/dirty' autoload :DynamicFinderMatch, 'active_record/dynamic_finder_match' + autoload :DynamicScopeMatch, 'active_record/dynamic_scope_match' autoload :Migration, 'active_record/migration' autoload :Migrator, 'active_record/migration' autoload :NamedScope, 'active_record/named_scope' diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index e5e94555eb..5198dbfa9b 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1456,7 +1456,10 @@ module ActiveRecord #:nodoc: def respond_to?(method_id, include_private = false) if match = DynamicFinderMatch.match(method_id) return true if all_attributes_exists?(match.attribute_names) + elsif match = DynamicScopeMatch.match(method_id) + return true if all_attributes_exists?(match.attribute_names) end + super end @@ -1809,7 +1812,11 @@ module ActiveRecord #:nodoc: # This also enables you to initialize a record if it is not found, such as find_or_initialize_by_amount(amount) # or find_or_create_by_user_and_password(user, password). # - # Each dynamic finder or initializer/creator is also defined in the class after it is first invoked, so that future + # Also enables dynamic scopes like scoped_by_user_name(user_name) and scoped_by_user_name_and_password(user_name, password) that + # are turned into scoped(:conditions => ["user_name = ?", user_name]) and scoped(:conditions => ["user_name = ? AND password = ?", user_name, password]) + # respectively. + # + # Each dynamic finder, scope or initializer/creator is also defined in the class after it is first invoked, so that future # attempts to use it do not run through method_missing. def method_missing(method_id, *arguments, &block) if match = DynamicFinderMatch.match(method_id) @@ -1868,6 +1875,22 @@ module ActiveRecord #:nodoc: }, __FILE__, __LINE__ send(method_id, *arguments, &block) end + elsif match = DynamicScopeMatch.match(method_id) + attribute_names = match.attribute_names + super unless all_attributes_exists?(attribute_names) + if match.scope? + self.class_eval %{ + def self.#{method_id}(*args) # def self.scoped_by_user_name_and_password(*args) + options = args.extract_options! # options = args.extract_options! + attributes = construct_attributes_from_arguments( # attributes = construct_attributes_from_arguments( + [:#{attribute_names.join(',:')}], args # [:user_name, :password], args + ) # ) + # + scoped(:conditions => attributes) # scoped(:conditions => attributes) + end # end + }, __FILE__, __LINE__ + send(method_id, *arguments) + end else super end diff --git a/activerecord/lib/active_record/dynamic_scope_match.rb b/activerecord/lib/active_record/dynamic_scope_match.rb new file mode 100644 index 0000000000..f796ba669a --- /dev/null +++ b/activerecord/lib/active_record/dynamic_scope_match.rb @@ -0,0 +1,25 @@ +module ActiveRecord + class DynamicScopeMatch + def self.match(method) + ds_match = self.new(method) + ds_match.scope ? ds_match : nil + end + + def initialize(method) + @scope = true + case method.to_s + when /^scoped_by_([_a-zA-Z]\w*)$/ + names = $1 + else + @scope = nil + end + @attribute_names = names && names.split('_and_') + end + + attr_reader :scope, :attribute_names + + def scope? + !@scope.nil? + end + end +end diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb index 64e899780c..b152f95a15 100644 --- a/activerecord/test/cases/named_scope_test.rb +++ b/activerecord/test/cases/named_scope_test.rb @@ -278,3 +278,23 @@ class NamedScopeTest < ActiveRecord::TestCase assert_equal post.comments.size, Post.scoped(:joins => join).scoped(:joins => join, :conditions => "posts.id = #{post.id}").size end end + +class DynamicScopeMatchTest < ActiveRecord::TestCase + def test_scoped_by_no_match + assert_nil ActiveRecord::DynamicScopeMatch.match("not_scoped_at_all") + end + + def test_scoped_by + match = ActiveRecord::DynamicScopeMatch.match("scoped_by_age_and_sex_and_location") + assert_not_nil match + assert match.scope? + assert_equal %w(age sex location), match.attribute_names + end +end + +class DynamicScopeTest < ActiveRecord::TestCase + def test_dynamic_scope + assert_equal Post.scoped_by_author_id(1).find(1), Post.find(1) + assert_equal Post.scoped_by_author_id_and_title(1, "Welcome to the weblog").first, Post.find(:first, :conditions => { :author_id => 1, :title => "Welcome to the weblog"}) + end +end -- cgit v1.2.3 From 220dff4c3b58b7becb587ee6f2434b2ca720f7c3 Mon Sep 17 00:00:00 2001 From: Mike Gunderloy Date: Mon, 29 Dec 2008 20:46:20 -0600 Subject: Add transaction check to SQLite2 adapter to fix test_sqlite_add_column_in_transaction_raises_statement_invalid [#1669 state:resolved] Signed-off-by: Pratik Naik --- activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb index 84f8c0284e..9387cf8827 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb @@ -402,6 +402,10 @@ module ActiveRecord end def add_column(table_name, column_name, type, options = {}) #:nodoc: + if @connection.respond_to?(:transaction_active?) && @connection.transaction_active? + raise StatementInvalid, 'Cannot add columns to a SQLite database while inside a transaction' + end + alter_table(table_name) do |definition| definition.column(column_name, type, options) end -- cgit v1.2.3 From a29369ae4ac705fbbd4ac0c0325468e50e4eeca0 Mon Sep 17 00:00:00 2001 From: Mike Gunderloy Date: Mon, 29 Dec 2008 19:14:30 -0600 Subject: Fix named scope tests for sqlite3 [#1667 state:resolved] Signed-off-by: Pratik Naik --- activerecord/test/cases/named_scope_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb index b152f95a15..bab842cf66 100644 --- a/activerecord/test/cases/named_scope_test.rb +++ b/activerecord/test/cases/named_scope_test.rb @@ -254,7 +254,7 @@ class NamedScopeTest < ActiveRecord::TestCase end def test_should_use_where_in_query_for_named_scope - assert_equal Developer.find_all_by_name('Jamis'), Developer.find_all_by_id(Developer.jamises) + assert_equal Developer.find_all_by_name('Jamis').to_set, Developer.find_all_by_id(Developer.jamises).to_set end def test_size_should_use_count_when_results_are_not_loaded -- cgit v1.2.3