aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib')
-rw-r--r--activerecord/lib/active_record/aggregations.rb5
-rwxr-xr-xactiverecord/lib/active_record/associations.rb48
-rw-r--r--activerecord/lib/active_record/associations/association_collection.rb1
-rw-r--r--activerecord/lib/active_record/associations/association_proxy.rb3
-rw-r--r--activerecord/lib/active_record/associations/has_many_association.rb4
-rw-r--r--activerecord/lib/active_record/attribute_methods/dirty.rb18
-rwxr-xr-xactiverecord/lib/active_record/base.rb52
-rw-r--r--activerecord/lib/active_record/callbacks.rb10
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb23
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql_adapter.rb14
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb4
-rw-r--r--activerecord/lib/active_record/dynamic_finder_match.rb3
-rw-r--r--activerecord/lib/active_record/migration.rb6
-rw-r--r--activerecord/lib/active_record/nested_attributes.rb7
-rw-r--r--activerecord/lib/active_record/railtie.rb5
-rw-r--r--activerecord/lib/active_record/railties/databases.rake2
-rw-r--r--activerecord/lib/active_record/railties/log_subscriber.rb7
-rw-r--r--activerecord/lib/active_record/reflection.rb8
-rw-r--r--activerecord/lib/active_record/relation.rb7
-rw-r--r--activerecord/lib/active_record/relation/finder_methods.rb13
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb19
-rw-r--r--activerecord/lib/active_record/relation/spawn_methods.rb36
-rw-r--r--activerecord/lib/rails/generators/active_record.rb (renamed from activerecord/lib/generators/active_record.rb)0
-rw-r--r--activerecord/lib/rails/generators/active_record/migration/migration_generator.rb (renamed from activerecord/lib/generators/active_record/migration/migration_generator.rb)2
-rw-r--r--activerecord/lib/rails/generators/active_record/migration/templates/migration.rb (renamed from activerecord/lib/generators/active_record/migration/templates/migration.rb)0
-rw-r--r--activerecord/lib/rails/generators/active_record/model/model_generator.rb (renamed from activerecord/lib/generators/active_record/model/model_generator.rb)2
-rw-r--r--activerecord/lib/rails/generators/active_record/model/templates/migration.rb (renamed from activerecord/lib/generators/active_record/model/templates/migration.rb)0
-rw-r--r--activerecord/lib/rails/generators/active_record/model/templates/model.rb (renamed from activerecord/lib/generators/active_record/model/templates/model.rb)0
-rw-r--r--activerecord/lib/rails/generators/active_record/observer/observer_generator.rb (renamed from activerecord/lib/generators/active_record/observer/observer_generator.rb)2
-rw-r--r--activerecord/lib/rails/generators/active_record/observer/templates/observer.rb (renamed from activerecord/lib/generators/active_record/observer/templates/observer.rb)0
-rw-r--r--activerecord/lib/rails/generators/active_record/session_migration/session_migration_generator.rb (renamed from activerecord/lib/generators/active_record/session_migration/session_migration_generator.rb)2
-rw-r--r--activerecord/lib/rails/generators/active_record/session_migration/templates/migration.rb (renamed from activerecord/lib/generators/active_record/session_migration/templates/migration.rb)0
32 files changed, 180 insertions, 123 deletions
diff --git a/activerecord/lib/active_record/aggregations.rb b/activerecord/lib/active_record/aggregations.rb
index 9ecf231a66..08389907ef 100644
--- a/activerecord/lib/active_record/aggregations.rb
+++ b/activerecord/lib/active_record/aggregations.rb
@@ -213,6 +213,11 @@ module ActiveRecord
module_eval do
define_method(name) do |*args|
force_reload = args.first || false
+
+ unless instance_variable_defined?("@#{name}")
+ instance_variable_set("@#{name}", nil)
+ end
+
if (instance_variable_get("@#{name}").nil? || force_reload) && (!allow_nil || mapping.any? {|pair| !read_attribute(pair.first).nil? })
attrs = mapping.collect {|pair| read_attribute(pair.first)}
object = case constructor
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index b69577f8dd..d623ddb915 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.
@@ -1207,7 +1210,7 @@ module ActiveRecord
# * <tt>Developer#projects.empty?</tt>
# * <tt>Developer#projects.size</tt>
# * <tt>Developer#projects.find(id)</tt>
- # * <tt>Developer#clients.exists?(...)</tt>
+ # * <tt>Developer#projects.exists?(...)</tt>
# * <tt>Developer#projects.build</tt> (similar to <tt>Project.new("project_id" => id)</tt>)
# * <tt>Developer#projects.create</tt> (similar to <tt>c = Project.new("project_id" => id); c.save; c</tt>)
# The declaration may include an options hash to specialize the behavior of the association.
@@ -1542,15 +1545,19 @@ module ActiveRecord
case name
when :destroy, :delete
- define_method(method_name) do
- association = send(reflection.name)
- association.send(name) if association
- end
+ class_eval <<-eoruby, __FILE__, __LINE__ + 1
+ def #{method_name}
+ association = #{reflection.name}
+ association.#{name} if association
+ end
+ eoruby
when :nullify
- define_method(method_name) do
- association = send(reflection.name)
- association.update_attribute(reflection.primary_key_name, nil) if association
- end
+ class_eval <<-eoruby, __FILE__, __LINE__ + 1
+ def #{method_name}
+ association = #{reflection.name}
+ association.update_attribute(#{reflection.primary_key_name.inspect}, nil) if association
+ end
+ eoruby
else
raise ArgumentError, "The :dependent option expects either :destroy, :delete or :nullify (#{reflection.options[:dependent].inspect})"
end
@@ -1568,10 +1575,12 @@ module ActiveRecord
end
method_name = :"belongs_to_dependent_#{name}_for_#{reflection.name}"
- define_method(method_name) do
- association = send(reflection.name)
- association.send(name) if association
- end
+ class_eval <<-eoruby, __FILE__, __LINE__ + 1
+ def #{method_name}
+ association = #{reflection.name}
+ association.#{name} if association
+ end
+ eoruby
after_destroy method_name
end
end
@@ -1670,15 +1679,6 @@ module ActiveRecord
reflection
end
- def using_limitable_reflections?(reflections)
- reflections.collect(&:collection?).length.zero?
- end
-
- def column_aliases(join_dependency)
- join_dependency.joins.collect{|join| join.column_names_with_alias.collect{|column_name, aliased_name|
- "#{connection.quote_table_name join.aliased_table_name}.#{connection.quote_column_name column_name} AS #{aliased_name}"}}.flatten.join(", ")
- end
-
def add_association_callbacks(association_name, options)
callbacks = %w(before_add after_add before_remove after_remove)
callbacks.each do |callback_name|
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..4fb1df3ab9 100644
--- a/activerecord/lib/active_record/associations/association_proxy.rb
+++ b/activerecord/lib/active_record/associations/association_proxy.rb
@@ -49,10 +49,11 @@ 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
+ @updated = false
reflection.check_validity!
Array(reflection.options[:extend]).each { |ext| proxy_extend(ext) }
reset
diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb
index 146a6ca55f..0464e8ceea 100644
--- a/activerecord/lib/active_record/associations/has_many_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_association.rb
@@ -5,6 +5,10 @@ module ActiveRecord
# If the association has a <tt>:through</tt> option further specialization
# is provided by its child HasManyThroughAssociation.
class HasManyAssociation < AssociationCollection #:nodoc:
+ def initialize(owner, reflection)
+ @finder_sql = nil
+ super
+ end
protected
def owner_quoted_id
if @reflection.options[:primary_key]
diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb
index 4a3ab9ea82..a8698a2f5a 100644
--- a/activerecord/lib/active_record/attribute_methods/dirty.rb
+++ b/activerecord/lib/active_record/attribute_methods/dirty.rb
@@ -18,7 +18,7 @@ module ActiveRecord
def save_with_dirty(*args) #:nodoc:
if status = save_without_dirty(*args)
@previously_changed = changes
- changed_attributes.clear
+ @changed_attributes.clear
end
status
end
@@ -26,16 +26,16 @@ module ActiveRecord
# Attempts to <tt>save!</tt> the record and clears changed attributes if successful.
def save_with_dirty!(*args) #:nodoc:
save_without_dirty!(*args).tap do
- @previously_changed = changes
- changed_attributes.clear
+ @previously_changed = changes
+ @changed_attributes.clear
end
end
# <tt>reload</tt> the record and clears changed attributes.
def reload_with_dirty(*args) #:nodoc:
reload_without_dirty(*args).tap do
- previously_changed_attributes.clear
- changed_attributes.clear
+ @previously_changed.clear
+ @changed_attributes.clear
end
end
@@ -45,12 +45,12 @@ module ActiveRecord
attr = attr.to_s
# The attribute already has an unsaved change.
- if changed_attributes.include?(attr)
- old = changed_attributes[attr]
- changed_attributes.delete(attr) unless field_changed?(attr, old, value)
+ if attribute_changed?(attr)
+ old = @changed_attributes[attr]
+ @changed_attributes.delete(attr) unless field_changed?(attr, old, value)
else
old = clone_attribute_value(:read_attribute, attr)
- changed_attributes[attr] = old if field_changed?(attr, old, value)
+ @changed_attributes[attr] = old if field_changed?(attr, old, value)
end
# Carry on.
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 52587ef251..367b4ce217 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -1041,6 +1041,12 @@ 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.instance_variable_set(:@previously_changed, {})
+ object.instance_variable_set(:@changed_attributes, {})
object.send(:_run_find_callbacks)
object.send(:_run_initialize_callbacks)
@@ -1506,6 +1512,12 @@ module ActiveRecord #:nodoc:
@attributes = attributes_from_column_definition
@attributes_cache = {}
@new_record = true
+ @readonly = false
+ @destroyed = false
+ @marked_for_destruction = false
+ @previously_changed = {}
+ @changed_attributes = {}
+
ensure_proper_type
if scope = self.class.send(:current_scoped_methods)
@@ -1570,7 +1582,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 +1609,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 +1707,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 +1924,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 +1951,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)
@@ -2042,26 +2054,6 @@ module ActiveRecord #:nodoc:
end
# Returns a copy of the attributes hash where all the values have been safely quoted for use in
- # an SQL statement.
- def attributes_with_quotes(include_primary_key = true, include_readonly_attributes = true, attribute_names = @attributes.keys)
- quoted = {}
- connection = self.class.connection
- attribute_names.each do |name|
- if (column = column_for_attribute(name)) && (include_primary_key || !column.primary)
- value = read_attribute(name)
-
- # We need explicit to_yaml because quote() does not properly convert Time/Date fields to YAML.
- if value && self.class.serialized_attributes.has_key?(name) && (value.acts_like?(:date) || value.acts_like?(:time))
- value = value.to_yaml
- end
-
- quoted[name] = connection.quote(value, column)
- end
- end
- include_readonly_attributes ? quoted : remove_readonly_attributes(quoted)
- end
-
- # Returns a copy of the attributes hash where all the values have been safely quoted for use in
# an Arel insert/update method.
def arel_attributes_values(include_primary_key = true, include_readonly_attributes = true, attribute_names = @attributes.keys)
attrs = {}
@@ -2245,4 +2237,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/callbacks.rb b/activerecord/lib/active_record/callbacks.rb
index 1128286f2b..add5d99ca6 100644
--- a/activerecord/lib/active_record/callbacks.rb
+++ b/activerecord/lib/active_record/callbacks.rb
@@ -205,6 +205,16 @@ module ActiveRecord
# including <tt>after_*</tt> hooks. Note, however, that in that case the client
# needs to be aware of it because an ordinary +save+ will raise such exception
# instead of quietly returning +false+.
+ #
+ # == Debugging callbacks
+ #
+ # To list the methods and procs registered with a particular callback, append <tt>_callback_chain</tt> to the callback name that you wish to list and send that to your class from the Rails console:
+ #
+ # >> Topic.after_save_callback_chain
+ # => [#<ActiveSupport::Callbacks::Callback:0x3f6a448
+ # @method=#<Proc:0x03f9a42c@/Users/foo/bar/app/models/topic.rb:43>, kind:after_save, identifiernil,
+ # options{}]
+ #
module Callbacks
extend ActiveSupport::Concern
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
index abb695264e..0c87e052c4 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -181,6 +181,29 @@ module ActiveRecord
# done if the transaction block raises an exception or returns false.
def rollback_db_transaction() end
+ # Appends +LIMIT+ and +OFFSET+ options to an SQL statement, or some SQL
+ # fragment that has the same semantics as LIMIT and OFFSET.
+ #
+ # +options+ must be a Hash which contains a +:limit+ option
+ # and an +:offset+ option.
+ #
+ # This method *modifies* the +sql+ parameter.
+ #
+ # ===== Examples
+ # add_limit_offset!('SELECT * FROM suppliers', {:limit => 10, :offset => 50})
+ # generates
+ # SELECT * FROM suppliers LIMIT 10 OFFSET 50
+
+ def add_limit_offset!(sql, options)
+ if limit = options[:limit]
+ sql << " LIMIT #{sanitize_limit(limit)}"
+ end
+ if offset = options[:offset]
+ sql << " OFFSET #{offset.to_i}"
+ end
+ sql
+ end
+
def default_sequence_name(table, column)
nil
end
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 1f1df7e8c3..521bd810d0 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -61,7 +61,7 @@ module ActiveRecord
begin
require_library_or_gem('mysql')
rescue LoadError
- $stderr.puts '!!! The bundled mysql.rb driver has been removed from Rails 2.2. Please install the mysql gem and try again: gem install mysql.'
+ $stderr.puts '!!! Please install the mysql gem and try again: gem install mysql.'
raise
end
end
@@ -375,6 +375,18 @@ module ActiveRecord
execute("RELEASE SAVEPOINT #{current_savepoint_name}")
end
+ def add_limit_offset!(sql, options) #:nodoc:
+ limit, offset = options[:limit], options[:offset]
+ if limit && offset
+ sql << " LIMIT #{offset.to_i}, #{sanitize_limit(limit)}"
+ elsif limit
+ sql << " LIMIT #{sanitize_limit(limit)}"
+ elsif offset
+ sql << " OFFSET #{offset.to_i}"
+ end
+ sql
+ end
+
# SCHEMA STATEMENTS ========================================
def structure_dump #:nodoc:
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index b3ce8c79dd..c9a5f00dfd 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -651,14 +651,12 @@ module ActiveRecord
end
end
-
# Returns the list of all tables in the schema search path or a specified schema.
def tables(name = nil)
- schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',')
query(<<-SQL, name).map { |row| row[0] }
SELECT tablename
FROM pg_tables
- WHERE schemaname IN (#{schemas})
+ WHERE schemaname = ANY (current_schemas(false))
SQL
end
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..d4cda927ad 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
@@ -372,7 +374,7 @@ module ActiveRecord
end
def load_migration
- load(filename)
+ require(File.expand_path(filename))
name.constantize
end
diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb
index d8fae495e7..76ec7eb681 100644
--- a/activerecord/lib/active_record/nested_attributes.rb
+++ b/activerecord/lib/active_record/nested_attributes.rb
@@ -243,11 +243,14 @@ module ActiveRecord
# def pirate_attributes=(attributes)
# assign_nested_attributes_for_one_to_one_association(:pirate, attributes)
# end
- class_eval %{
+ class_eval <<-eoruby, __FILE__, __LINE__ + 1
+ if method_defined?(:#{association_name}_attributes=)
+ remove_method(:#{association_name}_attributes=)
+ end
def #{association_name}_attributes=(attributes)
assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes)
end
- }, __FILE__, __LINE__
+ eoruby
else
raise ArgumentError, "No association found for name `#{association_name}'. Has it been defined yet?"
end
diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb
index 60addd46c6..de47461c73 100644
--- a/activerecord/lib/active_record/railtie.rb
+++ b/activerecord/lib/active_record/railtie.rb
@@ -10,7 +10,7 @@ require "action_controller/railtie"
module ActiveRecord
class Railtie < Rails::Railtie
- railtie_name :active_record
+ config.active_record = ActiveSupport::OrderedOptions.new
config.generators.orm :active_record, :migration => true,
:timestamps => true
@@ -19,9 +19,8 @@ module ActiveRecord
load "active_record/railties/databases.rake"
end
- # TODO If we require the wrong file, the error never comes up.
require "active_record/railties/log_subscriber"
- log_subscriber ActiveRecord::Railties::LogSubscriber.new
+ log_subscriber :active_record, ActiveRecord::Railties::LogSubscriber.new
initializer "active_record.initialize_timezone" do
ActiveRecord.base_hook do
diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake
index fa6caa4910..0229793a9a 100644
--- a/activerecord/lib/active_record/railties/databases.rake
+++ b/activerecord/lib/active_record/railties/databases.rake
@@ -435,7 +435,7 @@ namespace :db do
task :create => :environment do
raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations?
require 'rails/generators'
- require 'generators/rails/session_migration/session_migration_generator'
+ require 'rails/generators/rails/session_migration/session_migration_generator'
Rails::Generators::SessionMigrationGenerator.start [ ENV["MIGRATION"] || "add_sessions_table" ]
end
diff --git a/activerecord/lib/active_record/railties/log_subscriber.rb b/activerecord/lib/active_record/railties/log_subscriber.rb
index 48b25032ce..31b98bb6ed 100644
--- a/activerecord/lib/active_record/railties/log_subscriber.rb
+++ b/activerecord/lib/active_record/railties/log_subscriber.rb
@@ -1,6 +1,11 @@
module ActiveRecord
module Railties
class LogSubscriber < Rails::LogSubscriber
+ def initialize
+ super
+ @odd_or_even = false
+ end
+
def sql(event)
name = '%s (%.1fms)' % [event.payload[:name], event.duration]
sql = event.payload[:sql].squeeze(' ')
@@ -24,4 +29,4 @@ module ActiveRecord
end
end
end
-end \ No newline at end of file
+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..a20c152eeb 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -14,6 +14,11 @@ module ActiveRecord
def initialize(klass, table)
@klass, @table = klass, table
+
+ @implicit_readonly = nil
+ @loaded = nil
+
+ SINGLE_VALUE_METHODS.each {|v| instance_variable_set(:"@#{v}_value", nil)}
(ASSOCIATION_METHODS + MULTI_VALUE_METHODS).each {|v| instance_variable_set(:"@#{v}_values", [])}
end
@@ -54,7 +59,7 @@ module ActiveRecord
preload = @preload_values
preload += @includes_values unless eager_loading?
- preload.each {|associations| @klass.send(:preload_associations, @records, associations) }
+ preload.each {|associations| @klass.send(:preload_associations, @records, associations) }
# @readonly_value is true only if set explicity. @implicit_readonly is true if there are JOINS and no explicit SELECT.
readonly = @readonly_value.nil? ? @implicit_readonly : @readonly_value
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb
index d6d3d66642..c1cce679b6 100644
--- a/activerecord/lib/active_record/relation/finder_methods.rb
+++ b/activerecord/lib/active_record/relation/finder_methods.rb
@@ -175,7 +175,7 @@ module ActiveRecord
end
def construct_relation_for_association_find(join_dependency)
- relation = except(:includes, :eager_load, :preload, :select).select(@klass.send(:column_aliases, join_dependency))
+ relation = except(:includes, :eager_load, :preload, :select).select(column_aliases(join_dependency))
apply_join_dependency(relation, join_dependency)
end
@@ -184,7 +184,7 @@ module ActiveRecord
relation = association.join_relation(relation)
end
- limitable_reflections = @klass.send(:using_limitable_reflections?, join_dependency.reflections)
+ limitable_reflections = using_limitable_reflections?(join_dependency.reflections)
if !limitable_reflections && relation.limit_value
limited_id_condition = construct_limited_ids_condition(relation.except(:select))
@@ -311,5 +311,14 @@ module ActiveRecord
end
end
+ def column_aliases(join_dependency)
+ join_dependency.joins.collect{|join| join.column_names_with_alias.collect{|column_name, aliased_name|
+ "#{connection.quote_table_name join.aliased_table_name}.#{connection.quote_column_name column_name} AS #{aliased_name}"}}.flatten.join(", ")
+ end
+
+ def using_limitable_reflections?(reflections)
+ reflections.collect(&:collection?).length.zero?
+ end
+
end
end
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index e00d9cdf27..0250e739b8 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -6,6 +6,7 @@ module ActiveRecord
(ActiveRecord::Relation::ASSOCIATION_METHODS + ActiveRecord::Relation::MULTI_VALUE_METHODS).each do |query_method|
attr_accessor :"#{query_method}_values"
+ next if [:where, :having].include?(query_method)
class_eval <<-CEVAL
def #{query_method}(*args)
new_relation = clone
@@ -133,13 +134,8 @@ module ActiveRecord
arel = h.is_a?(String) ? arel.having(h) : arel.having(*h)
end
- if defined?(@limit_value) && @limit_value.present?
- arel = arel.take(@limit_value)
- end
-
- if defined?(@offset_value) && @offset_value.present?
- arel = arel.skip(@offset_value)
- end
+ arel = arel.take(@limit_value) if @limit_value.present?
+ arel = arel.skip(@offset_value) if @offset_value.present?
@group_values.uniq.each do |g|
arel = arel.group(g) if g.present?
@@ -162,19 +158,14 @@ module ActiveRecord
arel = arel.project(quoted_table_name + '.*')
end
- arel =
- if defined?(@from_value) && @from_value.present?
- arel.from(@from_value)
- else
- arel.from(quoted_table_name)
- end
+ arel = @from_value.present? ? arel.from(@from_value) : arel.from(quoted_table_name)
case @lock_value
when TrueClass
arel = arel.lock
when String
arel = arel.lock(@lock_value)
- end if defined?(@lock_value)
+ end if @lock_value.present?
arel
end
diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb
index a18380f01c..2841ff1239 100644
--- a/activerecord/lib/active_record/relation/spawn_methods.rb
+++ b/activerecord/lib/active_record/relation/spawn_methods.rb
@@ -4,30 +4,14 @@ module ActiveRecord
merged_relation = clone
return merged_relation unless r
- merged_relation = merged_relation.eager_load(r.eager_load_values).preload(r.preload_values).includes(r.includes_values)
-
- merged_relation.readonly_value = r.readonly_value unless r.readonly_value.nil?
- merged_relation.limit_value = r.limit_value if r.limit_value.present?
- merged_relation.lock_value = r.lock_value unless merged_relation.lock_value
- merged_relation.offset_value = r.offset_value if r.offset_value.present?
-
- merged_relation = merged_relation.
- joins(r.joins_values).
- group(r.group_values).
- select(r.select_values).
- from(r.from_value).
- having(r.having_values)
-
- merged_relation.order_values = r.order_values if r.order_values.present?
-
- merged_relation.create_with_value = @create_with_value
-
- if @create_with_value && r.create_with_value
- merged_relation.create_with_value = @create_with_value.merge(r.create_with_value)
- else
- merged_relation.create_with_value = r.create_with_value || @create_with_value
+ (ActiveRecord::Relation::ASSOCIATION_METHODS + ActiveRecord::Relation::MULTI_VALUE_METHODS).reject {|m| [:joins, :where].include?(m)}.each do |method|
+ unless (value = r.send(:"#{method}_values")).blank?
+ merged_relation.send(:"#{method}_values=", value)
+ end
end
+ merged_relation = merged_relation.joins(r.joins_values)
+
merged_wheres = @where_values
r.where_values.each do |w|
@@ -40,6 +24,14 @@ module ActiveRecord
merged_relation.where_values = merged_wheres
+ ActiveRecord::Relation::SINGLE_VALUE_METHODS.reject {|m| m == :lock}.each do |method|
+ unless (value = r.send(:"#{method}_value")).nil?
+ merged_relation.send(:"#{method}_value=", value)
+ end
+ end
+
+ merged_relation.lock_value = r.lock_value unless merged_relation.lock_value
+
merged_relation
end
diff --git a/activerecord/lib/generators/active_record.rb b/activerecord/lib/rails/generators/active_record.rb
index 1ca838b4f2..1ca838b4f2 100644
--- a/activerecord/lib/generators/active_record.rb
+++ b/activerecord/lib/rails/generators/active_record.rb
diff --git a/activerecord/lib/generators/active_record/migration/migration_generator.rb b/activerecord/lib/rails/generators/active_record/migration/migration_generator.rb
index 7939977f72..f6159deeeb 100644
--- a/activerecord/lib/generators/active_record/migration/migration_generator.rb
+++ b/activerecord/lib/rails/generators/active_record/migration/migration_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/active_record'
+require 'rails/generators/active_record'
module ActiveRecord
module Generators
diff --git a/activerecord/lib/generators/active_record/migration/templates/migration.rb b/activerecord/lib/rails/generators/active_record/migration/templates/migration.rb
index bbb7c53d86..bbb7c53d86 100644
--- a/activerecord/lib/generators/active_record/migration/templates/migration.rb
+++ b/activerecord/lib/rails/generators/active_record/migration/templates/migration.rb
diff --git a/activerecord/lib/generators/active_record/model/model_generator.rb b/activerecord/lib/rails/generators/active_record/model/model_generator.rb
index 2641083e0d..3e72fbeca8 100644
--- a/activerecord/lib/generators/active_record/model/model_generator.rb
+++ b/activerecord/lib/rails/generators/active_record/model/model_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/active_record'
+require 'rails/generators/active_record'
module ActiveRecord
module Generators
diff --git a/activerecord/lib/generators/active_record/model/templates/migration.rb b/activerecord/lib/rails/generators/active_record/model/templates/migration.rb
index 1f68487304..1f68487304 100644
--- a/activerecord/lib/generators/active_record/model/templates/migration.rb
+++ b/activerecord/lib/rails/generators/active_record/model/templates/migration.rb
diff --git a/activerecord/lib/generators/active_record/model/templates/model.rb b/activerecord/lib/rails/generators/active_record/model/templates/model.rb
index 21ae29e9f2..21ae29e9f2 100644
--- a/activerecord/lib/generators/active_record/model/templates/model.rb
+++ b/activerecord/lib/rails/generators/active_record/model/templates/model.rb
diff --git a/activerecord/lib/generators/active_record/observer/observer_generator.rb b/activerecord/lib/rails/generators/active_record/observer/observer_generator.rb
index a6b57423b8..c1c0e3f25b 100644
--- a/activerecord/lib/generators/active_record/observer/observer_generator.rb
+++ b/activerecord/lib/rails/generators/active_record/observer/observer_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/active_record'
+require 'rails/generators/active_record'
module ActiveRecord
module Generators
diff --git a/activerecord/lib/generators/active_record/observer/templates/observer.rb b/activerecord/lib/rails/generators/active_record/observer/templates/observer.rb
index b9a3004161..b9a3004161 100644
--- a/activerecord/lib/generators/active_record/observer/templates/observer.rb
+++ b/activerecord/lib/rails/generators/active_record/observer/templates/observer.rb
diff --git a/activerecord/lib/generators/active_record/session_migration/session_migration_generator.rb b/activerecord/lib/rails/generators/active_record/session_migration/session_migration_generator.rb
index 59c4792066..afcda2a98a 100644
--- a/activerecord/lib/generators/active_record/session_migration/session_migration_generator.rb
+++ b/activerecord/lib/rails/generators/active_record/session_migration/session_migration_generator.rb
@@ -1,4 +1,4 @@
-require 'generators/active_record'
+require 'rails/generators/active_record'
module ActiveRecord
module Generators
diff --git a/activerecord/lib/generators/active_record/session_migration/templates/migration.rb b/activerecord/lib/rails/generators/active_record/session_migration/templates/migration.rb
index 919822af7b..919822af7b 100644
--- a/activerecord/lib/generators/active_record/session_migration/templates/migration.rb
+++ b/activerecord/lib/rails/generators/active_record/session_migration/templates/migration.rb