aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib')
-rwxr-xr-xactiverecord/lib/active_record/associations.rb12
-rwxr-xr-xactiverecord/lib/active_record/base.rb29
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql_adapter.rb7
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb2
-rw-r--r--activerecord/lib/active_record/validations.rb2
5 files changed, 38 insertions, 14 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 8b51a38f48..425d71ecc1 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1149,13 +1149,15 @@ module ActiveRecord
# <b>WARNING:</b> If you're overwriting the table name of either class, the +table_name+ method
# MUST be declared underneath any +has_and_belongs_to_many+ declaration in order to work.
# [:foreign_key]
- # Specify the foreign key used for the association. By default this is guessed to be the name
- # of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_and_belongs_to_many+ association
+ # Specify the foreign key used for the association (on "this side" of association).
+ # By default this is guessed to be the name of this class in lower-case and "_id" suffixed.
+ # So a Person class that makes a +has_and_belongs_to_many+ association to Project
# will use "person_id" as the default <tt>:foreign_key</tt>.
# [:association_foreign_key]
- # Specify the association foreign key used for the association. By default this is
- # guessed to be the name of the associated class in lower-case and "_id" suffixed. So if the associated class is Project,
- # the +has_and_belongs_to_many+ association will use "project_id" as the default <tt>:association_foreign_key</tt>.
+ # Specify the association foreign key used for the association (on the "other side" of association).
+ # By default this is guessed to be the name of the associated class in lower-case and "_id" suffixed.
+ # So if a Person class makes a +has_and_belongs_to_many+ association to Project,
+ # the association will use "project_id" as the default <tt>:association_foreign_key</tt>.
# [:conditions]
# Specify the conditions that the associated object must meet in order to be included as a +WHERE+
# SQL fragment, such as <tt>authorized = 1</tt>. Record creations from the association are scoped if a hash is used.
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index ebc0b7783f..0efccb66ee 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -927,7 +927,7 @@ module ActiveRecord #:nodoc:
#
# ==== Parameters
#
- # * +id+ - The id of the object you wish to update a counter on.
+ # * +id+ - The id of the object you wish to update a counter on or an Array of ids.
# * +counters+ - An Array of Hashes containing the names of the fields
# to update as keys and the amount to update the field by as values.
#
@@ -941,12 +941,27 @@ module ActiveRecord #:nodoc:
# # SET comment_count = comment_count - 1,
# # action_count = action_count + 1
# # WHERE id = 5
+ #
+ # # For the Posts with id of 10 and 15, increment the comment_count by 1
+ # Post.update_counters [10, 15], :comment_count => 1
+ # # Executes the following SQL:
+ # # UPDATE posts
+ # # SET comment_count = comment_count + 1,
+ # # WHERE id IN (10, 15)
def update_counters(id, counters)
updates = counters.inject([]) { |list, (counter_name, increment)|
sign = increment < 0 ? "-" : "+"
list << "#{connection.quote_column_name(counter_name)} = COALESCE(#{connection.quote_column_name(counter_name)}, 0) #{sign} #{increment.abs}"
}.join(", ")
- update_all(updates, "#{connection.quote_column_name(primary_key)} = #{quote_value(id)}")
+
+ if id.is_a?(Array)
+ ids_list = id.map {|i| quote_value(i)}.join(', ')
+ condition = "IN (#{ids_list})"
+ else
+ condition = "= #{quote_value(id)}"
+ end
+
+ update_all(updates, "#{connection.quote_column_name(primary_key)} #{condition}")
end
# Increment a number field by one, usually representing a count.
@@ -1700,7 +1715,7 @@ module ActiveRecord #:nodoc:
end
join
end
- joins.flatten.uniq
+ joins.flatten.map{|j| j.strip}.uniq
else
joins.collect{|j| safe_to_array(j)}.flatten.uniq
end
@@ -2097,7 +2112,11 @@ module ActiveRecord #:nodoc:
(hash[method].keys + params.keys).uniq.each do |key|
merge = hash[method][key] && params[key] # merge if both scopes have the same key
if key == :conditions && merge
- hash[method][key] = merge_conditions(params[key], hash[method][key])
+ if params[key].is_a?(Hash) && hash[method][key].is_a?(Hash)
+ hash[method][key] = merge_conditions(hash[method][key].deep_merge(params[key]))
+ else
+ hash[method][key] = merge_conditions(params[key], hash[method][key])
+ end
elsif key == :include && merge
hash[method][key] = merge_includes(hash[method][key], params[key]).uniq
elsif key == :joins && merge
@@ -2107,7 +2126,7 @@ module ActiveRecord #:nodoc:
end
end
else
- hash[method] = params.merge(hash[method])
+ hash[method] = hash[method].merge(params)
end
else
hash[method] = params
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index b2345fd571..9300df28ee 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -152,6 +152,7 @@ module ActiveRecord
# * <tt>:password</tt> - Defaults to nothing.
# * <tt>:database</tt> - The name of the database. No default, must be provided.
# * <tt>:encoding</tt> - (Optional) Sets the client encoding by executing "SET NAMES <encoding>" after connection.
+ # * <tt>:reconnect</tt> - Defaults to false (See MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html).
# * <tt>:sslca</tt> - Necessary to use MySQL with an SSL connection.
# * <tt>:sslkey</tt> - Necessary to use MySQL with an SSL connection.
# * <tt>:sslcert</tt> - Necessary to use MySQL with an SSL connection.
@@ -563,8 +564,6 @@ module ActiveRecord
private
def connect
- @connection.reconnect = true if @connection.respond_to?(:reconnect=)
-
encoding = @config[:encoding]
if encoding
@connection.options(Mysql::SET_CHARSET_NAME, encoding) rescue nil
@@ -575,6 +574,10 @@ module ActiveRecord
end
@connection.real_connect(*@connection_options)
+
+ # reconnect must be set after real_connect is called, because real_connect sets it to false internally
+ @connection.reconnect = !!@config[:reconnect] if @connection.respond_to?(:reconnect=)
+
configure_connection
end
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index 9387cf8827..5390f49f04 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -306,7 +306,7 @@ module ActiveRecord
end
def copy_table(from, to, options = {}) #:nodoc:
- options = options.merge(:id => !columns(from).detect{|c| c.name == 'id'}.nil?)
+ options = options.merge(:id => (!columns(from).detect{|c| c.name == 'id'}.nil? && 'id' == primary_key(from).to_s))
create_table(to, options) do |definition|
@definition = definition
columns(from).each do |column|
diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb
index 6a9690ba85..6d750accb0 100644
--- a/activerecord/lib/active_record/validations.rb
+++ b/activerecord/lib/active_record/validations.rb
@@ -904,7 +904,7 @@ module ActiveRecord
configuration.update(attr_names.extract_options!)
validates_each(attr_names, configuration) do |record, attr_name, value|
- unless (value.is_a?(Array) ? value : [value]).inject(true) { |v, r| (r.nil? || r.valid?) && v }
+ unless (value.is_a?(Array) ? value : [value]).collect { |r| r.nil? || r.valid? }.all?
record.errors.add(attr_name, :invalid, :default => configuration[:message], :value => value)
end
end