diff options
Diffstat (limited to 'activerecord')
11 files changed, 60 insertions, 20 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index b69577f8dd..a5179033f2 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -111,8 +111,11 @@ module ActiveRecord private # Gets the specified association instance if it responds to :loaded?, nil otherwise. def association_instance_get(name) - association = instance_variable_get("@#{name}") - association if association.respond_to?(:loaded?) + ivar = "@#{name}" + if instance_variable_defined?(ivar) + association = instance_variable_get(ivar) + association if association.respond_to?(:loaded?) + end end # Set the specified association instance. diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 9487d16123..6eda70d0ce 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -101,6 +101,7 @@ module ActiveRecord Array(@target) end end + alias_method :to_a, :to_ary def reset reset_target! diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb index 022dd2ae9b..0ff89df1e3 100644 --- a/activerecord/lib/active_record/associations/association_proxy.rb +++ b/activerecord/lib/active_record/associations/association_proxy.rb @@ -49,7 +49,7 @@ module ActiveRecord alias_method :proxy_respond_to?, :respond_to? alias_method :proxy_extend, :extend delegate :to_param, :to => :proxy_target - instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^object_id$)/ } + instance_methods.each { |m| undef_method m unless m =~ /^(?:nil\?|send|object_id|to_a)$|^__|proxy_/ } def initialize(owner, reflection) @owner, @reflection = owner, reflection diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 52587ef251..1488d9f967 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1041,6 +1041,10 @@ module ActiveRecord #:nodoc: object.instance_variable_set(:'@attributes', record) object.instance_variable_set(:'@attributes_cache', {}) + object.instance_variable_set(:@new_record, false) + object.instance_variable_set(:@readonly, false) + object.instance_variable_set(:@destroyed, false) + object.instance_variable_set(:@marked_for_destruction, false) object.send(:_run_find_callbacks) object.send(:_run_initialize_callbacks) @@ -1506,6 +1510,10 @@ module ActiveRecord #:nodoc: @attributes = attributes_from_column_definition @attributes_cache = {} @new_record = true + @readonly = false + @destroyed = false + @marked_for_destruction = false + ensure_proper_type if scope = self.class.send(:current_scoped_methods) @@ -1570,7 +1578,7 @@ module ActiveRecord #:nodoc: # user_path(user) # => "/users/Phusion" def to_param # We can't use alias_method here, because method 'id' optimizes itself on the fly. - (id = self.id) ? id.to_s : nil # Be sure to stringify the id for routes + id && id.to_s # Be sure to stringify the id for routes end # Returns a cache key that can be used to identify this record. @@ -1597,12 +1605,12 @@ 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? - @new_record || false + @new_record end # Returns true if this object has been destroyed, otherwise returns false. def destroyed? - @destroyed || false + @destroyed end # Returns if the record is persisted, i.e. it's not a new record and it was not destroyed. @@ -1695,7 +1703,7 @@ module ActiveRecord #:nodoc: # This is especially useful for boolean flags on existing records. The regular +update_attribute+ method # in Base is replaced with this when the validations module is mixed in, which it is by default. def update_attribute(name, value) - send(name.to_s + '=', value) + send("#{name}=", value) save(:validate => false) end @@ -1912,14 +1920,14 @@ module ActiveRecord #:nodoc: # Returns duplicated record with unfreezed attributes. def dup obj = super - obj.instance_variable_set('@attributes', instance_variable_get('@attributes').dup) + obj.instance_variable_set('@attributes', @attributes.dup) obj end # Returns +true+ if the record is read only. Records loaded through joins with piggy-back # attributes will be marked as read only since they cannot be saved. def readonly? - defined?(@readonly) && @readonly == true + @readonly end # Marks this record as read only. @@ -1939,10 +1947,10 @@ module ActiveRecord #:nodoc: protected def clone_attributes(reader_method = :read_attribute, attributes = {}) - self.attribute_names.inject(attributes) do |attrs, name| - attrs[name] = clone_attribute_value(reader_method, name) - attrs + attribute_names.each do |name| + attributes[name] = clone_attribute_value(reader_method, name) end + attributes end def clone_attribute_value(reader_method, attribute_name) @@ -2245,4 +2253,4 @@ end # TODO: Remove this and make it work with LAZY flag require 'active_record/connection_adapters/abstract_adapter' -ActiveRecord.run_base_hooks(ActiveRecord::Base)
\ No newline at end of file +ActiveRecord.run_base_hooks(ActiveRecord::Base) diff --git a/activerecord/lib/active_record/dynamic_finder_match.rb b/activerecord/lib/active_record/dynamic_finder_match.rb index 8f9f05ce36..fa7a19487c 100644 --- a/activerecord/lib/active_record/dynamic_finder_match.rb +++ b/activerecord/lib/active_record/dynamic_finder_match.rb @@ -7,6 +7,9 @@ module ActiveRecord def initialize(method) @finder = :first + @bang = false + @instantiator = nil + case method.to_s when /^find_(all_by|last_by|by)_([_a-zA-Z]\w*)$/ @finder = :last if $1 == 'last_by' diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb index fd5ffc6d77..5825482db7 100644 --- a/activerecord/lib/active_record/migration.rb +++ b/activerecord/lib/active_record/migration.rb @@ -315,7 +315,9 @@ module ActiveRecord end def announce(message) - text = "#{@version} #{name}: #{message}" + version = defined?(@version) ? @version : nil + + text = "#{version} #{name}: #{message}" length = [0, 75 - text.length].max write "== %s %s" % [text, "=" * length] end diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index 32b9a2aa87..5e8fc104cb 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -154,6 +154,11 @@ module ActiveRecord @klass ||= active_record.send(:compute_type, class_name) end + def initialize(macro, name, options, active_record) + super + @collection = [:has_many, :has_and_belongs_to_many].include?(macro) + end + # Returns a new, unsaved instance of the associated class. +options+ will # be passed to the class's constructor. def build_association(*options) @@ -256,9 +261,6 @@ module ActiveRecord # association. Returns +true+ if the +macro+ is one of +has_many+ or # +has_and_belongs_to_many+, +false+ otherwise. def collection? - if @collection.nil? - @collection = [:has_many, :has_and_belongs_to_many].include?(macro) - end @collection end diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index aca4629dd8..1a84f70a8e 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -14,6 +14,14 @@ module ActiveRecord def initialize(klass, table) @klass, @table = klass, table + + @readonly_value = nil + @create_with_value = nil + @implicit_readonly = nil + @limit_value = nil + @offset_value = nil + @loaded = nil + (ASSOCIATION_METHODS + MULTI_VALUE_METHODS).each {|v| instance_variable_set(:"@#{v}_values", [])} 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 608d5a3608..d47c8bba7d 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -18,10 +18,14 @@ require 'models/developer' class HasManyThroughAssociationsTest < ActiveRecord::TestCase fixtures :posts, :readers, :people, :comments, :authors, :owners, :pets, :toys, :jobs, :references, :companies - def test_associate_existing - assert_queries(2) { posts(:thinking);people(:david) } + # Dummies to force column loads so query counts are clean. + def setup + Person.create :first_name => 'gummy' + Reader.create :person_id => 0, :post_id => 0 + end - posts(:thinking).people + def test_associate_existing + assert_queries(2) { posts(:thinking); people(:david) } assert_queries(1) do posts(:thinking).people << people(:david) diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb index 9bc34bd750..d99fb44f01 100644 --- a/activerecord/test/cases/associations_test.rb +++ b/activerecord/test/cases/associations_test.rb @@ -180,6 +180,14 @@ class AssociationProxyTest < ActiveRecord::TestCase end end + if RUBY_VERSION < '1.9' + def test_splat_does_not_invoke_to_a_on_singular_targets + author = posts(:welcome).author + author.reload.target.expects(:to_a).never + [*author] + end + end + def setup_dangling_association josh = Author.create(:name => "Josh") p = Post.create(:title => "New on Edge", :body => "More cool stuff!", :author => josh) diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb index e831ebf36c..1fb59d3589 100644 --- a/activerecord/test/cases/helper.rb +++ b/activerecord/test/cases/helper.rb @@ -7,6 +7,7 @@ require 'config' require 'test/unit' require 'stringio' +require 'mocha' require 'active_record' require 'active_support/dependencies' |