diff options
Diffstat (limited to 'activerecord/lib/active_record')
10 files changed, 57 insertions, 30 deletions
diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb index 0008600418..944caacab6 100644 --- a/activerecord/lib/active_record/associations/has_one_association.rb +++ b/activerecord/lib/active_record/associations/has_one_association.rb @@ -26,11 +26,13 @@ module ActiveRecord load_target return self.target if !(target || record) - if (target != record) || record.changed? + + assigning_another_record = target != record + if assigning_another_record || record.changed? save &&= owner.persisted? transaction_if(save) do - remove_target!(options[:dependent]) if target && !target.destroyed? + remove_target!(options[:dependent]) if target && !target.destroyed? && assigning_another_record if record set_owner_attributes(record) diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index 86c27557b4..b5acf211d5 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -16,6 +16,7 @@ module ActiveRecord autoload_at 'active_record/connection_adapters/abstract/schema_definitions' do autoload :IndexDefinition autoload :ColumnDefinition + autoload :ChangeColumnDefinition autoload :TableDefinition autoload :Table autoload :AlterTable diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb index 138ab811dc..ee6ca4fb6f 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb @@ -206,6 +206,12 @@ module ActiveRecord true end + def type_cast(value, column) + return super unless value == true || value == false + + value ? 1 : 0 + end + # MySQL 4 technically support transaction isolation, but it is affected by a bug # where the transaction level gets persisted for the whole session: # diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb index 88c9494fc6..7b18b95c44 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb @@ -160,12 +160,6 @@ module ActiveRecord # QUOTING ================================================== - def type_cast(value, column) - return super unless value == true || value == false - - value ? 1 : 0 - end - def quote_string(string) #:nodoc: @connection.quote(string) end @@ -476,7 +470,11 @@ module ActiveRecord def exec_stmt(sql, name, binds) cache = {} - log(sql, name, binds) do + type_casted_binds = binds.map { |col, val| + [col, type_cast(val, col)] + } + + log(sql, name, type_casted_binds) do if binds.empty? stmt = @connection.prepare(sql) else @@ -487,7 +485,7 @@ module ActiveRecord end begin - stmt.execute(*binds.map { |col, val| type_cast(val, col) }) + stmt.execute(*type_casted_binds.map { |_, val| val }) rescue Mysql::Error => e # Older versions of MySQL leave the prepared statement in a bad # place when an error occurs. To support older mysql versions, we diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb index e9daa5d7ff..c1f978a081 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb @@ -86,8 +86,11 @@ module ActiveRecord case value when Range - return super(value, column) unless /range$/ =~ column.sql_type - PostgreSQLColumn.range_to_string(value) + if /range$/ =~ column.sql_type + PostgreSQLColumn.range_to_string(value) + else + super(value, column) + end when NilClass if column.array && array_member 'NULL' @@ -101,12 +104,21 @@ module ActiveRecord when 'point' then PostgreSQLColumn.point_to_string(value) when 'json' then PostgreSQLColumn.json_to_string(value) else - return super(value, column) unless column.array - PostgreSQLColumn.array_to_string(value, column, self) + if column.array + PostgreSQLColumn.array_to_string(value, column, self) + else + super(value, column) + end end when String - return super(value, column) unless 'bytea' == column.sql_type - { :value => value, :format => 1 } + if 'bytea' == column.sql_type + # Return a bind param hash with format as binary. + # See http://deveiate.org/code/pg/PGconn.html#method-i-exec_prepared-doc + # for more information + { value: value, format: 1 } + else + super(value, column) + end when Hash case column.sql_type when 'hstore' then PostgreSQLColumn.hstore_to_string(value) @@ -114,8 +126,11 @@ module ActiveRecord else super(value, column) end when IPAddr - return super(value, column) unless ['inet','cidr'].include? column.sql_type - PostgreSQLColumn.cidr_to_string(value) + if %w(inet cidr).include? column.sql_type + PostgreSQLColumn.cidr_to_string(value) + else + super(value, column) + end else super(value, column) end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 3668aecd4b..eecebdb4e5 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -783,11 +783,12 @@ module ActiveRecord def exec_cache(sql, name, binds) stmt_key = prepare_statement(sql) + type_casted_binds = binds.map { |col, val| + [col, type_cast(val, col)] + } - log(sql, name, binds, stmt_key) do - @connection.send_query_prepared(stmt_key, binds.map { |col, val| - type_cast(val, col) - }) + log(sql, name, type_casted_binds, stmt_key) do + @connection.send_query_prepared(stmt_key, type_casted_binds.map { |_, val| val }) @connection.block @connection.get_last_result end diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb index e5ad08b6b0..35a579f29b 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb @@ -291,8 +291,11 @@ module ActiveRecord end def exec_query(sql, name = nil, binds = []) - log(sql, name, binds) do + type_casted_binds = binds.map { |col, val| + [col, type_cast(val, col)] + } + log(sql, name, type_casted_binds) do # Don't cache statements if they are not prepared if without_prepared_statement?(binds) stmt = @connection.prepare(sql) @@ -307,9 +310,7 @@ module ActiveRecord stmt = cache[:stmt] cols = cache[:cols] ||= stmt.columns stmt.reset! - stmt.bind_params binds.map { |col, val| - type_cast(val, col) - } + stmt.bind_params type_casted_binds.map { |_, val| val } end ActiveRecord::Result.new(cols, stmt.to_a) diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index d93c26c130..96b5686ae0 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -109,7 +109,7 @@ module ActiveRecord elsif abstract_class? "#{super}(abstract)" elsif !connected? - "#{super}(no database connection)" + "#{super} (call '#{super}.connection' to establish a connection)" elsif table_exists? attr_list = columns.map { |c| "#{c.name}: #{c.type}" } * ', ' "#{super}(#{attr_list})" diff --git a/activerecord/lib/active_record/log_subscriber.rb b/activerecord/lib/active_record/log_subscriber.rb index 927fbab8f0..654ef21b07 100644 --- a/activerecord/lib/active_record/log_subscriber.rb +++ b/activerecord/lib/active_record/log_subscriber.rb @@ -23,6 +23,8 @@ module ActiveRecord def render_bind(column, value) if column if column.binary? + # This specifically deals with the PG adapter that casts bytea columns into a Hash. + value = value[:value] if value.is_a?(Hash) value = "<#{value.bytesize} bytes of binary data>" end diff --git a/activerecord/lib/active_record/store.rb b/activerecord/lib/active_record/store.rb index 301bc503c7..186a737561 100644 --- a/activerecord/lib/active_record/store.rb +++ b/activerecord/lib/active_record/store.rb @@ -15,9 +15,10 @@ module ActiveRecord # You can set custom coder to encode/decode your serialized attributes to/from different formats. # JSON, YAML, Marshal are supported out of the box. Generally it can be any wrapper that provides +load+ and +dump+. # - # NOTE - If you are using special PostgreSQL columns like +hstore+ or +json+ there is no need for - # the serialization provieded by +store+. You can simply use +store_accessor+ instead to generate - # the accessor methods. + # NOTE - If you are using PostgreSQL specific columns like +hstore+ or +json+ there is no need for + # the serialization provided by +store+. Simply use +store_accessor+ instead to generate + # the accessor methods. Be aware that these columns use a string keyed hash and do not allow access + # using a symbol. # # Examples: # |