diff options
Diffstat (limited to 'activerecord/lib')
29 files changed, 132 insertions, 137 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 0efa111d12..58725246c8 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1,4 +1,3 @@ -require 'active_support/core_ext/array/wrap' require 'active_support/core_ext/enumerable' require 'active_support/core_ext/module/delegation' require 'active_support/core_ext/object/blank' diff --git a/activerecord/lib/active_record/associations/association_scope.rb b/activerecord/lib/active_record/associations/association_scope.rb index 090f690f0d..8a17f0ced4 100644 --- a/activerecord/lib/active_record/associations/association_scope.rb +++ b/activerecord/lib/active_record/associations/association_scope.rb @@ -15,7 +15,7 @@ module ActiveRecord def scope scope = klass.unscoped - scope = scope.extending(*Array.wrap(options[:extend])) + scope = scope.extending(*Array(options[:extend])) # It's okay to just apply all these like this. The options will only be present if the # association supports that option; this is enforced by the association builder. diff --git a/activerecord/lib/active_record/associations/builder/collection_association.rb b/activerecord/lib/active_record/associations/builder/collection_association.rb index 35f9a3ae8e..768f70b6c9 100644 --- a/activerecord/lib/active_record/associations/builder/collection_association.rb +++ b/activerecord/lib/active_record/associations/builder/collection_association.rb @@ -32,7 +32,7 @@ module ActiveRecord::Associations::Builder private def wrap_block_extension - options[:extend] = Array.wrap(options[:extend]) + options[:extend] = Array(options[:extend]) if block_extension silence_warnings do @@ -51,7 +51,7 @@ module ActiveRecord::Associations::Builder # TODO : why do i need method_defined? I think its because of the inheritance chain model.class_attribute full_callback_name.to_sym unless model.method_defined?(full_callback_name) - model.send("#{full_callback_name}=", Array.wrap(options[callback_name.to_sym])) + model.send("#{full_callback_name}=", Array(options[callback_name.to_sym])) end def define_readers diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb index fe9f30bd2a..7aed64d48c 100644 --- a/activerecord/lib/active_record/associations/collection_association.rb +++ b/activerecord/lib/active_record/associations/collection_association.rb @@ -1,5 +1,3 @@ -require 'active_support/core_ext/array/wrap' - module ActiveRecord module Associations # = Active Record Association Collection @@ -67,7 +65,7 @@ module ActiveRecord # Implements the ids writer method, e.g. foo.item_ids= for Foo.has_many :items def ids_writer(ids) pk_column = reflection.primary_key_column - ids = Array.wrap(ids).reject { |id| id.blank? } + ids = Array(ids).reject { |id| id.blank? } ids.map! { |i| pk_column.type_cast(i) } replace(klass.find(ids).index_by { |r| r.id }.values_at(*ids)) end @@ -400,12 +398,7 @@ module ActiveRecord return memory if persisted.empty? persisted.map! do |record| - # Unfortunately we cannot simply do memory.delete(record) since on 1.8 this returns - # record rather than memory.at(memory.index(record)). The behavior is fixed in 1.9. - mem_index = memory.index(record) - - if mem_index - mem_record = memory.delete_at(mem_index) + if mem_record = memory.delete(record) (record.attribute_names - mem_record.changes.keys).each do |name| mem_record[name] = record[name] diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb index eb320bc774..ba01df00e3 100644 --- a/activerecord/lib/active_record/associations/collection_proxy.rb +++ b/activerecord/lib/active_record/associations/collection_proxy.rb @@ -52,7 +52,7 @@ module ActiveRecord def initialize(association) @association = association - Array.wrap(association.options[:extend]).each { |ext| proxy_extend(ext) } + Array(association.options[:extend]).each { |ext| proxy_extend(ext) } end alias_method :new, :build diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb index c5834e2fef..02543db2ce 100644 --- a/activerecord/lib/active_record/attribute_methods.rb +++ b/activerecord/lib/active_record/attribute_methods.rb @@ -20,13 +20,15 @@ module ActiveRecord # Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example, # "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)). # (Alias for the protected read_attribute method). - alias [] read_attribute + def [](attr_name) + read_attribute(attr_name) + end # Updates the attribute identified by <tt>attr_name</tt> with the specified +value+. # (Alias for the protected write_attribute method). - alias []= write_attribute - - public :[], :[]= + def []=(attr_name, value) + write_attribute(attr_name, value) + end end module ClassMethods diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb index c86eaba498..8031912669 100644 --- a/activerecord/lib/active_record/autosave_association.rb +++ b/activerecord/lib/active_record/autosave_association.rb @@ -1,5 +1,3 @@ -require 'active_support/core_ext/array/wrap' - module ActiveRecord # = Active Record Autosave Association # diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index d29cf82dad..d4d0220fb7 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1,8 +1,3 @@ -begin - require 'psych' -rescue LoadError -end - require 'yaml' require 'set' require 'active_support/benchmarkable' @@ -12,7 +7,6 @@ require 'active_support/time' require 'active_support/core_ext/class/attribute' require 'active_support/core_ext/class/attribute_accessors' require 'active_support/core_ext/class/delegating_attributes' -require 'active_support/core_ext/class/attribute' require 'active_support/core_ext/array/extract_options' require 'active_support/core_ext/hash/deep_merge' require 'active_support/core_ext/hash/indifferent_access' diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb index 8b2fc69b00..a050fabf35 100644 --- a/activerecord/lib/active_record/callbacks.rb +++ b/activerecord/lib/active_record/callbacks.rb @@ -1,5 +1,3 @@ -require 'active_support/core_ext/array/wrap' - module ActiveRecord # = Active Record Callbacks # diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index 20d3b4a1ef..bfd5121a70 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -1,4 +1,3 @@ -require 'active_support/core_ext/array/wrap' require 'active_support/deprecation/reporting' module ActiveRecord @@ -42,7 +41,7 @@ module ActiveRecord # # Check an index with a custom name exists # index_exists?(:suppliers, :company_id, :name => "idx_company_id" def index_exists?(table_name, column_name, options = {}) - column_names = Array.wrap(column_name) + column_names = Array(column_name) index_name = options.key?(:name) ? options[:name].to_s : index_name(table_name, :column => column_names) if options[:unique] indexes(table_name).any?{ |i| i.unique && i.name == index_name } @@ -377,7 +376,7 @@ module ActiveRecord def index_name(table_name, options) #:nodoc: if Hash === options # legacy support if options[:column] - "index_#{table_name}_on_#{Array.wrap(options[:column]) * '_and_'}" + "index_#{table_name}_on_#{Array(options[:column]) * '_and_'}" elsif options[:name] options[:name] else @@ -420,23 +419,11 @@ module ActiveRecord end add_index sm_table, :version, :unique => true, :name => "#{Base.table_name_prefix}unique_schema_migrations#{Base.table_name_suffix}" - - # Backwards-compatibility: if we find schema_info, assume we've - # migrated up to that point: - si_table = Base.table_name_prefix + 'schema_info' + Base.table_name_suffix - - if table_exists?(si_table) - ActiveRecord::Deprecation.warn "Usage of the schema table `#{si_table}` is deprecated. Please switch to using `schema_migrations` table" - - old_version = select_value("SELECT version FROM #{quote_table_name(si_table)}").to_i - assume_migrated_upto_version(old_version) - drop_table(si_table) - end end end def assume_migrated_upto_version(version, migrations_paths = ActiveRecord::Migrator.migrations_paths) - migrations_paths = Array.wrap(migrations_paths) + migrations_paths = Array(migrations_paths) version = version.to_i sm_table = quote_table_name(ActiveRecord::Migrator.schema_migrations_table_name) @@ -551,7 +538,7 @@ module ActiveRecord end def add_index_options(table_name, column_name, options = {}) - column_names = Array.wrap(column_name) + column_names = Array(column_name) index_name = index_name(table_name, :column => column_names) if Hash === options # legacy support, since this param was a string diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index d2361b5378..e6ddf8bf8f 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -10,21 +10,23 @@ module ActiveRecord module ConnectionHandling # Establishes a connection to the database that's used by all Active Record objects def postgresql_connection(config) # :nodoc: - config = config.symbolize_keys - host = config[:host] - port = config[:port] || 5432 - username = config[:username].to_s if config[:username] - password = config[:password].to_s if config[:password] + conn_params = config.symbolize_keys - if config.key?(:database) - database = config[:database] - else - raise ArgumentError, "No database specified. Missing argument: database." + # Forward any unused config params to PGconn.connect. + [:statement_limit, :encoding, :min_messages, :schema_search_path, + :schema_order, :adapter, :pool, :wait_timeout, + :reaping_frequency].each do |key| + conn_params.delete key end + conn_params.delete_if { |k,v| v.nil? } + + # Map ActiveRecords param names to PGs. + conn_params[:user] = conn_params.delete(:username) if conn_params[:username] + conn_params[:dbname] = conn_params.delete(:database) if conn_params[:database] # The postgres drivers don't allow the creation of an unconnected PGconn object, # so just pass a nil connection object for the time being. - ConnectionAdapters::PostgreSQLAdapter.new(nil, logger, [host, port, nil, nil, database, username, password], config) + ConnectionAdapters::PostgreSQLAdapter.new(nil, logger, conn_params, config) end end @@ -226,22 +228,29 @@ module ActiveRecord end end - # The PostgreSQL adapter works both with the native C (http://ruby.scripting.ca/postgres/) and the pure - # Ruby (available both as gem and from http://rubyforge.org/frs/?group_id=234&release_id=1944) drivers. + # The PostgreSQL adapter works with the native C (https://bitbucket.org/ged/ruby-pg) driver. # # Options: # - # * <tt>:host</tt> - Defaults to "localhost". + # * <tt>:host</tt> - Defaults to a Unix-domain socket in /tmp. On machines without Unix-domain sockets, + # the default is to connect to localhost. # * <tt>:port</tt> - Defaults to 5432. - # * <tt>:username</tt> - Defaults to nothing. - # * <tt>:password</tt> - Defaults to nothing. - # * <tt>:database</tt> - The name of the database. No default, must be provided. + # * <tt>:username</tt> - Defaults to be the same as the operating system name of the user running the application. + # * <tt>:password</tt> - Password to be used if the server demands password authentication. + # * <tt>:database</tt> - Defaults to be the same as the user name. # * <tt>:schema_search_path</tt> - An optional schema search path for the connection given # as a string of comma-separated schema names. This is backward-compatible with the <tt>:schema_order</tt> option. # * <tt>:encoding</tt> - An optional client encoding that is used in a <tt>SET client_encoding TO # <encoding></tt> call on the connection. # * <tt>:min_messages</tt> - An optional client min messages that is used in a # <tt>SET client_min_messages TO <min_messages></tt> call on the connection. + # + # Any further options are used as connection parameters to libpq. See + # http://www.postgresql.org/docs/9.1/static/libpq-connect.html for the + # list of parameters. + # + # In addition, default connection parameters of libpq can be set per environment variables. + # See http://www.postgresql.org/docs/9.1/static/libpq-envars.html . class PostgreSQLAdapter < AbstractAdapter class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition def xml(*args) @@ -1200,7 +1209,7 @@ module ActiveRecord # Connects to a PostgreSQL server and sets up the adapter depending on the # connected server's characteristics. def connect - @connection = PGconn.connect(*@connection_parameters) + @connection = PGconn.connect(@connection_parameters) # Money type has a fixed precision of 10 in PostgreSQL 8.2 and below, and as of # PostgreSQL 8.3 it has a fixed precision of 19. PostgreSQLColumn.extract_precision diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index 980f8fe50f..89f6eccbd2 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -210,7 +210,7 @@ module ActiveRecord @attributes = cloned_attributes - _run_after_initialize_callbacks if respond_to?(:_run_after_initialize_callbacks) + _run_initialize_callbacks if _initialize_callbacks.any? @changed_attributes = {} self.class.column_defaults.each do |attr, orig_value| @@ -317,26 +317,6 @@ module ActiveRecord "#<#{self.class} #{inspection}>" end - # Hackery to accomodate Syck. Remove for 4.0. - def to_yaml(opts = {}) #:nodoc: - if YAML.const_defined?(:ENGINE) && !YAML::ENGINE.syck? - super - else - coder = {} - encode_with(coder) - YAML.quick_emit(self, opts) do |out| - out.map(taguri, to_yaml_style) do |map| - coder.each { |k, v| map.add(k, v) } - end - end - end - end - - # Hackery to accomodate Syck. Remove for 4.0. - def yaml_initialize(tag, coder) #:nodoc: - init_with(coder) - end - private # Under Ruby 1.9, Array#flatten will call #to_ary (recursively) on each of the elements diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb index 9ea8cf864c..cf315b687c 100644 --- a/activerecord/lib/active_record/fixtures.rb +++ b/activerecord/lib/active_record/fixtures.rb @@ -1,14 +1,7 @@ require 'erb' - -begin - require 'psych' -rescue LoadError -end - require 'yaml' require 'zlib' require 'active_support/dependencies' -require 'active_support/core_ext/array/wrap' require 'active_support/core_ext/object/blank' require 'active_support/ordered_hash' require 'active_record/fixtures/file' @@ -789,7 +782,7 @@ module ActiveRecord end def setup_fixture_accessors(fixture_names = nil) - fixture_names = Array.wrap(fixture_names || fixture_table_names) + fixture_names = Array(fixture_names || fixture_table_names) methods = Module.new do fixture_names.each do |fixture_name| fixture_name = fixture_name.to_s diff --git a/activerecord/lib/active_record/fixtures/file.rb b/activerecord/lib/active_record/fixtures/file.rb index 6bad36abb9..6547791144 100644 --- a/activerecord/lib/active_record/fixtures/file.rb +++ b/activerecord/lib/active_record/fixtures/file.rb @@ -1,8 +1,3 @@ -begin - require 'psych' -rescue LoadError -end - require 'erb' require 'yaml' diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb index 46464783fd..10073e2b37 100644 --- a/activerecord/lib/active_record/migration.rb +++ b/activerecord/lib/active_record/migration.rb @@ -1,6 +1,6 @@ require "active_support/core_ext/module/delegation" require "active_support/core_ext/class/attribute_accessors" -require "active_support/core_ext/array/wrap" +require 'active_support/deprecation' module ActiveRecord # Exception that can be raised to stop migrations from going backwards. @@ -345,12 +345,24 @@ module ActiveRecord @name = self.class.name @version = nil @connection = nil + @reverting = false end # instantiate the delegate object after initialize is defined self.verbose = true self.delegate = new + def revert + @reverting = true + yield + ensure + @reverting = false + end + + def reverting? + @reverting + end + def up self.class.delegate = self return unless self.class.respond_to?(:up) @@ -384,9 +396,11 @@ module ActiveRecord end @connection = conn time = Benchmark.measure { - recorder.inverse.each do |cmd, args| - send(cmd, *args) - end + self.revert { + recorder.inverse.each do |cmd, args| + send(cmd, *args) + end + } } else time = Benchmark.measure { change } @@ -441,9 +455,11 @@ module ActiveRecord arg_list = arguments.map{ |a| a.inspect } * ', ' say_with_time "#{method}(#{arg_list})" do - unless arguments.empty? || method == :execute - arguments[0] = Migrator.proper_table_name(arguments.first) - arguments[1] = Migrator.proper_table_name(arguments.second) if method == :rename_table + unless reverting? + unless arguments.empty? || method == :execute + arguments[0] = Migrator.proper_table_name(arguments.first) + arguments[1] = Migrator.proper_table_name(arguments.second) if method == :rename_table + end end return super unless connection.respond_to?(method) connection.send(method, *arguments, &block) @@ -508,7 +524,7 @@ module ActiveRecord File.basename(filename) end - delegate :migrate, :announce, :write, :to=>:migration + delegate :migrate, :announce, :write, :to => :migration private @@ -587,18 +603,17 @@ module ActiveRecord def migrations_paths @migrations_paths ||= ['db/migrate'] # just to not break things if someone uses: migration_path = some_string - Array.wrap(@migrations_paths) + Array(@migrations_paths) end def migrations_path migrations_paths.first end - def migrations(paths, subdirectories = true) - paths = Array.wrap(paths) + def migrations(paths) + paths = Array(paths) - glob = subdirectories ? "**/" : "" - files = Dir[*paths.map { |p| "#{p}/#{glob}[0-9]*_*.rb" }] + files = Dir[*paths.map { |p| "#{p}/**/[0-9]*_*.rb" }] seen = Hash.new false diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb index a8ee43b598..9e21039c4f 100644 --- a/activerecord/lib/active_record/nested_attributes.rb +++ b/activerecord/lib/active_record/nested_attributes.rb @@ -382,7 +382,7 @@ module ActiveRecord if attributes_collection.is_a? Hash keys = attributes_collection.keys attributes_collection = if keys.include?('id') || keys.include?(:id) - Array.wrap(attributes_collection) + [attributes_collection] else attributes_collection.values end diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb index 165d0750dd..b1c8ae5b77 100644 --- a/activerecord/lib/active_record/railtie.rb +++ b/activerecord/lib/active_record/railtie.rb @@ -38,7 +38,7 @@ module ActiveRecord # first time. Also, make it output to STDERR. console do |app| require "active_record/railties/console_sandbox" if app.sandbox? - ActiveRecord::Base.logger = Logger.new(STDERR) + ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDERR) end initializer "active_record.initialize_timezone" do diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index 60b73e9fe5..f02f0544c5 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -175,7 +175,7 @@ module ActiveRecord def initialize(macro, name, options, active_record) super - @collection = macro.in?([:has_many, :has_and_belongs_to_many]) + @collection = [:has_many, :has_and_belongs_to_many].include?(macro) end # Returns a new, unsaved instance of the associated class. +options+ will diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 6f2248fa21..bf1de4ba9d 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -8,7 +8,7 @@ module ActiveRecord JoinOperation = Struct.new(:relation, :join_class, :on) ASSOCIATION_METHODS = [:includes, :eager_load, :preload] MULTI_VALUE_METHODS = [:select, :group, :order, :joins, :where, :having, :bind] - SINGLE_VALUE_METHODS = [:limit, :offset, :lock, :readonly, :from, :reorder, :reverse_order, :uniq] + SINGLE_VALUE_METHODS = [:limit, :offset, :lock, :readonly, :from, :reordering, :reverse_order, :uniq] include FinderMethods, Calculations, SpawnMethods, QueryMethods, Batches, Explain, Delegation diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index e58c726e09..f1ac421a50 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -134,7 +134,7 @@ module ActiveRecord def last(*args) if args.any? if args.first.kind_of?(Integer) || (loaded? && !args.first.kind_of?(Hash)) - if order_values.empty? && reorder_value.nil? + if order_values.empty? order("#{primary_key} DESC").limit(*args).reverse else to_a.last(*args) @@ -249,7 +249,7 @@ module ActiveRecord end def construct_limited_ids_condition(relation) - orders = (relation.reorder_value || relation.order_values).map { |val| val.presence }.compact + orders = relation.order_values.map { |val| val.presence }.compact values = @klass.connection.distinct("#{@klass.connection.quote_table_name table_name}.#{primary_key}", orders) relation = relation.dup diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index bfb5c27578..44ff8f7b22 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -9,7 +9,7 @@ module ActiveRecord :select_values, :group_values, :order_values, :joins_values, :where_values, :having_values, :bind_values, :limit_value, :offset_value, :lock_value, :readonly_value, :create_with_value, - :from_value, :reorder_value, :reverse_order_value, + :from_value, :reordering_value, :reverse_order_value, :uniq_value def includes(*args) @@ -107,7 +107,8 @@ module ActiveRecord return self if args.blank? relation = clone - relation.reorder_value = args.flatten + relation.reordering_value = true + relation.order_values = args.flatten relation end @@ -273,7 +274,7 @@ module ActiveRecord arel.group(*@group_values.uniq.reject{|g| g.blank?}) unless @group_values.empty? - order = @reorder_value ? @reorder_value : @order_values + order = @order_values order = reverse_sql_order(order) if @reverse_order_value arel.order(*order.uniq.reject{|o| o.blank?}) unless order.empty? diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb index a5194beae5..de639a48f2 100644 --- a/activerecord/lib/active_record/relation/spawn_methods.rb +++ b/activerecord/lib/active_record/relation/spawn_methods.rb @@ -22,7 +22,7 @@ module ActiveRecord end end - (Relation::MULTI_VALUE_METHODS - [:joins, :where]).each do |method| + (Relation::MULTI_VALUE_METHODS - [:joins, :where, :order]).each do |method| value = r.send(:"#{method}_values") merged_relation.send(:"#{method}_values=", merged_relation.send(:"#{method}_values") + value) if value.present? end @@ -48,7 +48,7 @@ module ActiveRecord merged_relation.where_values = merged_wheres - (Relation::SINGLE_VALUE_METHODS - [:lock, :create_with]).each do |method| + (Relation::SINGLE_VALUE_METHODS - [:lock, :create_with, :reordering]).each do |method| value = r.send(:"#{method}_value") merged_relation.send(:"#{method}_value=", value) unless value.nil? end @@ -57,6 +57,15 @@ module ActiveRecord merged_relation = merged_relation.create_with(r.create_with_value) unless r.create_with_value.empty? + if (r.reordering_value) + # override any order specified in the original relation + merged_relation.reordering_value = true + merged_relation.order_values = r.order_values + else + # merge in order_values from r + merged_relation.order_values += r.order_values + end + # Apply scope extension modules merged_relation.send :apply_modules, r.extensions diff --git a/activerecord/lib/active_record/schema_dumper.rb b/activerecord/lib/active_record/schema_dumper.rb index cdde5cf3b9..2a565b51c6 100644 --- a/activerecord/lib/active_record/schema_dumper.rb +++ b/activerecord/lib/active_record/schema_dumper.rb @@ -112,7 +112,7 @@ HEADER # AR has an optimization which handles zero-scale decimals as integers. This # code ensures that the dumper still dumps the column as a decimal. - spec[:type] = if column.type == :integer && [/^numeric/, /^decimal/].any? { |e| e.match(column.sql_type) } + spec[:type] = if column.type == :integer && /^(numeric|decimal)/ =~ column.sql_type 'decimal' else column.type.to_s @@ -127,10 +127,14 @@ HEADER end.compact # find all migration keys used in this table - keys = [:name, :limit, :precision, :scale, :default, :null] & column_specs.map{ |k| k.keys }.flatten + keys = [:name, :limit, :precision, :scale, :default, :null] # figure out the lengths for each column based on above keys - lengths = keys.map{ |key| column_specs.map{ |spec| spec[key] ? spec[key].length + 2 : 0 }.max } + lengths = keys.map { |key| + column_specs.map { |spec| + spec[key] ? spec[key].length + 2 : 0 + }.max + } # the string we're going to sprintf our values against, with standardized column widths format_string = lengths.map{ |len| "%-#{len}s" } diff --git a/activerecord/lib/active_record/serialization.rb b/activerecord/lib/active_record/serialization.rb index 5ad40d8cd9..41e3b92499 100644 --- a/activerecord/lib/active_record/serialization.rb +++ b/activerecord/lib/active_record/serialization.rb @@ -7,8 +7,8 @@ module ActiveRecord #:nodoc: def serializable_hash(options = nil) options = options.try(:clone) || {} - options[:except] = Array.wrap(options[:except]).map { |n| n.to_s } - options[:except] |= Array.wrap(self.class.inheritance_column) + options[:except] = Array(options[:except]).map { |n| n.to_s } + options[:except] |= Array(self.class.inheritance_column) super(options) end diff --git a/activerecord/lib/active_record/serializers/xml_serializer.rb b/activerecord/lib/active_record/serializers/xml_serializer.rb index 0e7f57aa43..7f1dba5095 100644 --- a/activerecord/lib/active_record/serializers/xml_serializer.rb +++ b/activerecord/lib/active_record/serializers/xml_serializer.rb @@ -1,4 +1,3 @@ -require 'active_support/core_ext/array/wrap' require 'active_support/core_ext/hash/conversions' module ActiveRecord #:nodoc: @@ -179,7 +178,7 @@ module ActiveRecord #:nodoc: class XmlSerializer < ActiveModel::Serializers::Xml::Serializer #:nodoc: def initialize(*args) super - options[:except] = Array.wrap(options[:except]) | Array.wrap(@serializable.class.inheritance_column) + options[:except] = Array(options[:except]) | Array(@serializable.class.inheritance_column) end class Attribute < ActiveModel::Serializers::Xml::Serializer::Attribute #:nodoc: diff --git a/activerecord/lib/active_record/session_store.rb b/activerecord/lib/active_record/session_store.rb index 1029bed064..ce43ae8066 100644 --- a/activerecord/lib/active_record/session_store.rb +++ b/activerecord/lib/active_record/session_store.rb @@ -116,7 +116,7 @@ module ActiveRecord define_method(:session_id) { sessid } define_method(:session_id=) { |session_id| self.sessid = session_id } else - class << self; remove_method :find_by_session_id; end + class << self; remove_possible_method :find_by_session_id; end def self.find_by_session_id(session_id) find :first, :conditions => {:session_id=>session_id} diff --git a/activerecord/lib/active_record/test_case.rb b/activerecord/lib/active_record/test_case.rb index 5398a14fc6..64ecef2077 100644 --- a/activerecord/lib/active_record/test_case.rb +++ b/activerecord/lib/active_record/test_case.rb @@ -9,6 +9,10 @@ module ActiveRecord cleanup_identity_map end + def teardown + ActiveRecord::SQLCounter.log.clear + end + def cleanup_identity_map ActiveRecord::IdentityMap.clear end @@ -49,5 +53,9 @@ module ActiveRecord ensure ActiveRecord::SQLCounter.ignored_sql = prev_ignored_sql end + + def sqlite3? connection + connection.class.name.split('::').last == "SQLite3Adapter" + end end end diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb index 2c70d31b94..b492377d18 100644 --- a/activerecord/lib/active_record/transactions.rb +++ b/activerecord/lib/active_record/transactions.rb @@ -211,7 +211,7 @@ module ActiveRecord def after_commit(*args, &block) options = args.last if options.is_a?(Hash) && options[:on] - options[:if] = Array.wrap(options[:if]) + options[:if] = Array(options[:if]) options[:if] << "transaction_include_action?(:#{options[:on]})" end set_callback(:commit, :after, *args, &block) @@ -220,7 +220,7 @@ module ActiveRecord def after_rollback(*args, &block) options = args.last if options.is_a?(Hash) && options[:on] - options[:if] = Array.wrap(options[:if]) + options[:if] = Array(options[:if]) options[:if] << "transaction_include_action?(:#{options[:on]})" end set_callback(:rollback, :after, *args, &block) diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb index 2e2ea8c42b..3a741ba600 100644 --- a/activerecord/lib/active_record/validations/uniqueness.rb +++ b/activerecord/lib/active_record/validations/uniqueness.rb @@ -1,5 +1,3 @@ -require 'active_support/core_ext/array/wrap' - module ActiveRecord module Validations class UniquenessValidator < ActiveModel::EachValidator @@ -25,8 +23,13 @@ module ActiveRecord relation = build_relation(finder_class, table, attribute, value) relation = relation.and(table[finder_class.primary_key.to_sym].not_eq(record.send(:id))) if record.persisted? - Array.wrap(options[:scope]).each do |scope_item| + Array(options[:scope]).each do |scope_item| scope_value = record.send(scope_item) + reflection = record.class.reflect_on_association(scope_item) + if reflection + scope_value = record.send(reflection.foreign_key) + scope_item = reflection.foreign_key + end relation = relation.and(table[scope_item].eq(scope_value)) end @@ -53,14 +56,22 @@ module ActiveRecord end def build_relation(klass, table, attribute, value) #:nodoc: - column = klass.columns_hash[attribute.to_s] - value = column.limit ? value.to_s.mb_chars[0, column.limit] : value.to_s if column.text? + reflection = klass.reflect_on_association(attribute) + column = nil + if(reflection) + column = klass.columns_hash[reflection.foreign_key] + attribute = reflection.foreign_key + value = value.attributes[reflection.primary_key_column.name] + else + column = klass.columns_hash[attribute.to_s] + end + value = column.limit ? value.to_s[0, column.limit] : value.to_s if !value.nil? && column.text? if !options[:case_sensitive] && value && column.text? # will use SQL LOWER function before comparison, unless it detects a case insensitive collation relation = klass.connection.case_insensitive_comparison(table, attribute, column, value) else - value = klass.connection.case_sensitive_modifier(value) + value = klass.connection.case_sensitive_modifier(value) unless value.nil? relation = table[attribute].eq(value) end @@ -81,7 +92,7 @@ module ActiveRecord # # class Person < ActiveRecord::Base # validates_uniqueness_of :user_name, :scope => :account_id - # end + # end # # Or even multiple scope parameters. For example, making sure that a teacher can only be on the schedule once # per semester for a particular class. |