aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/associations/through_association_scope.rb2
-rw-r--r--activerecord/lib/active_record/base.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb8
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb60
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb27
-rw-r--r--activerecord/lib/active_record/persistence.rb15
-rw-r--r--activerecord/lib/active_record/railtie.rb13
-rw-r--r--activerecord/lib/active_record/relation.rb4
-rw-r--r--activerecord/lib/active_record/timestamp.rb36
-rw-r--r--activerecord/test/cases/adapters/sqlite/sqlite_adapter_test.rb118
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb2
-rw-r--r--activerecord/test/cases/associations/has_one_through_associations_test.rb12
-rw-r--r--activerecord/test/cases/json_serialization_test.rb7
-rw-r--r--activerecord/test/cases/relation_scoping_test.rb6
-rw-r--r--activerecord/test/cases/timestamp_test.rb10
-rw-r--r--activerecord/test/fixtures/dashboards.yml3
-rw-r--r--activerecord/test/fixtures/minivans.yml4
-rw-r--r--activerecord/test/fixtures/speedometers.yml4
-rw-r--r--activerecord/test/models/dashboard.rb3
-rw-r--r--activerecord/test/models/developer.rb1
-rw-r--r--activerecord/test/models/minivan.rb6
-rw-r--r--activerecord/test/models/speedometer.rb4
-rw-r--r--activerecord/test/schema/schema.rb17
23 files changed, 264 insertions, 100 deletions
diff --git a/activerecord/lib/active_record/associations/through_association_scope.rb b/activerecord/lib/active_record/associations/through_association_scope.rb
index 22e1033a9d..cabb33c4a8 100644
--- a/activerecord/lib/active_record/associations/through_association_scope.rb
+++ b/activerecord/lib/active_record/associations/through_association_scope.rb
@@ -35,7 +35,7 @@ module ActiveRecord
@owner.class.base_class.name.to_s,
reflection.klass.columns_hash["#{as}_type"]) }
elsif reflection.macro == :belongs_to
- { reflection.klass.primary_key => @owner[reflection.primary_key_name] }
+ { reflection.klass.primary_key => @owner.class.quote_value(@owner[reflection.primary_key_name]) }
else
{ reflection.primary_key_name => owner_quoted_id }
end
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index c78060c956..400a0adbcf 100644
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -398,7 +398,7 @@ module ActiveRecord #:nodoc:
delegate :find, :first, :last, :all, :destroy, :destroy_all, :exists?, :delete, :delete_all, :update, :update_all, :to => :scoped
delegate :find_each, :find_in_batches, :to => :scoped
- delegate :select, :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :create_with, :to => :scoped
+ delegate :select, :group, :order, :reorder, :limit, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :create_with, :to => :scoped
delegate :count, :average, :minimum, :maximum, :sum, :calculate, :to => :scoped
# Executes a custom SQL query against your database and returns all the results. The results will
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb
index 23c42d670b..8e74eff0ab 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb
@@ -66,15 +66,9 @@ module ActiveRecord
unless spec.key?(:adapter) then raise AdapterNotSpecified, "database configuration does not specify adapter" end
begin
- require 'rubygems'
- gem "activerecord-#{spec[:adapter]}-adapter"
require "active_record/connection_adapters/#{spec[:adapter]}_adapter"
rescue LoadError
- begin
- require "active_record/connection_adapters/#{spec[:adapter]}_adapter"
- rescue LoadError
- raise "Please install the #{spec[:adapter]} adapter: `gem install activerecord-#{spec[:adapter]}-adapter` (#{$!})"
- end
+ raise "Please install the #{spec[:adapter]} adapter: `gem install activerecord-#{spec[:adapter]}-adapter` (#{$!})"
end
adapter_method = "#{spec[:adapter]}_connection"
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 2fe2ae7136..dd623def2e 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -431,15 +431,15 @@ module ActiveRecord
def result_as_array(res) #:nodoc:
# check if we have any binary column and if they need escaping
unescape_col = []
- for j in 0...res.nfields do
+ res.nfields.times do |j|
# unescape string passed BYTEA field (OID == 17)
unescape_col << ( res.ftype(j)==17 )
end
ary = []
- for i in 0...res.ntuples do
+ res.ntuples.times do |i|
ary << []
- for j in 0...res.nfields do
+ res.nfields.times do |j|
data = res.getvalue(i,j)
data = unescape_bytea(data) if unescape_col[j] and data.is_a?(String)
ary[i] << data
@@ -941,51 +941,37 @@ module ActiveRecord
# conversions that are required to be performed here instead of in PostgreSQLColumn.
def select(sql, name = nil)
fields, rows = select_raw(sql, name)
- result = []
- for row in rows
- row_hash = {}
- fields.each_with_index do |f, i|
- row_hash[f] = row[i]
- end
- result << row_hash
+ rows.map do |row|
+ Hash[*fields.zip(row).flatten]
end
- result
end
def select_raw(sql, name = nil)
res = execute(sql, name)
results = result_as_array(res)
- fields = []
- rows = []
- if res.ntuples > 0
- fields = res.fields
- results.each do |row|
- hashed_row = {}
- row.each_index do |cell_index|
- # If this is a money type column and there are any currency symbols,
- # then strip them off. Indeed it would be prettier to do this in
- # PostgreSQLColumn.string_to_decimal but would break form input
- # fields that call value_before_type_cast.
- if res.ftype(cell_index) == MONEY_COLUMN_TYPE_OID
- # Because money output is formatted according to the locale, there are two
- # cases to consider (note the decimal separators):
- # (1) $12,345,678.12
- # (2) $12.345.678,12
- case column = row[cell_index]
- when /^-?\D+[\d,]+\.\d{2}$/ # (1)
- row[cell_index] = column.gsub(/[^-\d\.]/, '')
- when /^-?\D+[\d\.]+,\d{2}$/ # (2)
- row[cell_index] = column.gsub(/[^-\d,]/, '').sub(/,/, '.')
- end
+ fields = res.fields
+ results.each do |row|
+ row.each_with_index do |cell, cell_index|
+ # If this is a money type column and there are any currency symbols,
+ # then strip them off. Indeed it would be prettier to do this in
+ # PostgreSQLColumn.string_to_decimal but would break form input
+ # fields that call value_before_type_cast.
+ if res.ftype(cell_index) == MONEY_COLUMN_TYPE_OID
+ # Because money output is formatted according to the locale, there are two
+ # cases to consider (note the decimal separators):
+ # (1) $12,345,678.12
+ # (2) $12.345.678,12
+ case cell
+ when /^-?\D+[\d,]+\.\d{2}$/ # (1)
+ cell.gsub!(/[^-\d\.]/, '')
+ when /^-?\D+[\d\.]+,\d{2}$/ # (2)
+ cell.gsub!(/[^-\d,]/, '').sub!(/,/, '.')
end
-
- hashed_row[fields[cell_index]] = column
end
- rows << row
end
end
res.clear
- return fields, rows
+ return fields, results
end
# Returns the list of a table's column names, data types, and default values.
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index 117cf447df..e812a0371b 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -190,16 +190,21 @@ module ActiveRecord
def indexes(table_name, name = nil) #:nodoc:
execute("PRAGMA index_list(#{quote_table_name(table_name)})", name).map do |row|
- index = IndexDefinition.new(table_name, row['name'])
- index.unique = row['unique'].to_i != 0
- index.columns = execute("PRAGMA index_info('#{index.name}')").map { |col| col['name'] }
- index
+ IndexDefinition.new(
+ table_name,
+ row['name'],
+ row['unique'].to_i != 0,
+ execute("PRAGMA index_info('#{row['name']}')").map { |col|
+ col['name']
+ })
end
end
def primary_key(table_name) #:nodoc:
- column = table_structure(table_name).find {|field| field['pk'].to_i == 1}
- column ? column['name'] : nil
+ column = table_structure(table_name).find { |field|
+ field['pk'].to_i == 1
+ }
+ column && column['name']
end
def remove_index!(table_name, index_name) #:nodoc:
@@ -278,10 +283,8 @@ module ActiveRecord
def select(sql, name = nil) #:nodoc:
execute(sql, name).map do |row|
record = {}
- row.each_key do |key|
- if key.is_a?(String)
- record[key.sub(/^"?\w+"?\./, '')] = row[key]
- end
+ row.each do |key, value|
+ record[key.sub(/^"?\w+"?\./, '')] = value if key.is_a?(String)
end
record
end
@@ -378,9 +381,9 @@ module ActiveRecord
def default_primary_key_type
if supports_autoincrement?
- 'INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL'.freeze
+ 'INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL'
else
- 'INTEGER PRIMARY KEY NOT NULL'.freeze
+ 'INTEGER PRIMARY KEY NOT NULL'
end
end
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index 828a8b41b6..e53cc5ee8c 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -105,18 +105,17 @@ module ActiveRecord
# Updates a single attribute and saves the record without going through the normal validation procedure
# or callbacks. This is especially useful for boolean flags on existing records.
def update_attribute(name, value)
- send("#{name}=", value)
- hash = { name => read_attribute(name) }
+ changes = record_update_timestamps || {}
- if record_update_timestamps
- timestamp_attributes_for_update_in_model.each do |column|
- hash[column] = read_attribute(column)
- end
+ if name
+ name = name.to_s
+ send("#{name}=", value)
+ changes[name] = read_attribute(name)
end
- @changed_attributes.delete(name.to_s)
+ @changed_attributes.except!(*changes.keys)
primary_key = self.class.primary_key
- self.class.update_all(hash, { primary_key => self[primary_key] }) == 1
+ self.class.update_all(changes, { primary_key => self[primary_key] }) == 1
end
# Updates all the attributes from the passed-in Hash and saves the record.
diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb
index 2808e199fe..eff51a7c87 100644
--- a/activerecord/lib/active_record/railtie.rb
+++ b/activerecord/lib/active_record/railtie.rb
@@ -16,11 +16,7 @@ module ActiveRecord
config.generators.orm :active_record, :migration => true,
:timestamps => true
- config.app_middleware.insert_after "::ActionDispatch::Callbacks",
- "ActiveRecord::QueryCache"
-
- config.app_middleware.insert_after "::ActionDispatch::Callbacks",
- "ActiveRecord::ConnectionAdapters::ConnectionManagement"
+ config.app_middleware.insert_after "::ActionDispatch::Callbacks", "ActiveRecord::QueryCache"
rake_tasks do
load "active_record/railties/databases.rake"
@@ -72,6 +68,13 @@ module ActiveRecord
end
end
+ initializer "active_record.add_concurrency_middleware" do |app|
+ if app.config.allow_concurrency
+ app.config.middleware.insert_after "::ActionDispatch::Callbacks",
+ "ActiveRecord::ConnectionAdapters::ConnectionManagement"
+ end
+ end
+
config.after_initialize do
ActiveSupport.on_load(:active_record) do
instantiate_observers
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index d9fc1b4940..7499100f55 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -10,7 +10,7 @@ module ActiveRecord
include FinderMethods, Calculations, SpawnMethods, QueryMethods, Batches
- delegate :to_xml, :to_json, :to_yaml, :length, :collect, :map, :each, :all?, :include?, :to => :to_a
+ delegate :to_xml, :to_yaml, :length, :collect, :map, :each, :all?, :include?, :to => :to_a
delegate :insert, :to => :arel
attr_reader :table, :klass
@@ -74,6 +74,8 @@ module ActiveRecord
@records
end
+ def as_json(options = nil) to_a end #:nodoc:
+
# Returns size of the records.
def size
loaded? ? @records.length : count
diff --git a/activerecord/lib/active_record/timestamp.rb b/activerecord/lib/active_record/timestamp.rb
index 1075a60f07..341cc87be5 100644
--- a/activerecord/lib/active_record/timestamp.rb
+++ b/activerecord/lib/active_record/timestamp.rb
@@ -21,27 +21,20 @@ module ActiveRecord
end
# Saves the record with the updated_at/on attributes set to the current time.
- # If the save fails because of validation errors, an
- # ActiveRecord::RecordInvalid exception is raised. If an attribute name is passed,
- # that attribute is used for the touch instead of the updated_at/on attributes.
+ # Please note that no validation is performed and no callbacks are executed.
+ # If an attribute name is passed, that attribute is updated along with
+ # updated_at/on attributes.
#
# Examples:
#
- # product.touch # updates updated_at
- # product.touch(:designed_at) # updates the designed_at attribute
+ # product.touch # updates updated_at/on
+ # product.touch(:designed_at) # updates the designed_at attribute and updated_at/on
def touch(attribute = nil)
- current_time = current_time_from_proper_timezone
-
- if attribute
- write_attribute(attribute, current_time)
- else
- timestamp_attributes_for_update_in_model.each { |column| write_attribute(column.to_s, current_time) }
- end
-
- save!
+ update_attribute(attribute, current_time_from_proper_timezone)
end
private
+
def create #:nodoc:
if record_timestamps
current_time = current_time_from_proper_timezone
@@ -58,17 +51,16 @@ module ActiveRecord
end
def update(*args) #:nodoc:
- record_update_timestamps
+ record_update_timestamps if !partial_updates? || changed?
super
end
- def record_update_timestamps
- if record_timestamps && (!partial_updates? || changed?)
- current_time = current_time_from_proper_timezone
- timestamp_attributes_for_update_in_model.each { |column| write_attribute(column.to_s, current_time) }
- true
- else
- false
+ def record_update_timestamps #:nodoc:
+ return unless record_timestamps
+ current_time = current_time_from_proper_timezone
+ timestamp_attributes_for_update_in_model.inject({}) do |hash, column|
+ hash[column.to_s] = write_attribute(column.to_s, current_time)
+ hash
end
end
diff --git a/activerecord/test/cases/adapters/sqlite/sqlite_adapter_test.rb b/activerecord/test/cases/adapters/sqlite/sqlite_adapter_test.rb
index 69cfb00faf..ce0b2f5f5b 100644
--- a/activerecord/test/cases/adapters/sqlite/sqlite_adapter_test.rb
+++ b/activerecord/test/cases/adapters/sqlite/sqlite_adapter_test.rb
@@ -83,17 +83,127 @@ module ActiveRecord
assert_equal 0, @ctx.select_rows(count_sql).first.first
end
+ def test_tables
+ assert_equal %w{ items }, @ctx.tables
+
+ @ctx.execute <<-eosql
+ CREATE TABLE people (
+ id integer PRIMARY KEY AUTOINCREMENT,
+ number integer
+ )
+ eosql
+ assert_equal %w{ items people }.sort, @ctx.tables.sort
+ end
+
+ def test_tables_logs_name
+ name = "hello"
+ assert_logged [[name]] do
+ @ctx.tables(name)
+ assert_not_nil @ctx.logged.first.shift
+ end
+ end
+
+ def test_columns
+ columns = @ctx.columns('items').sort_by { |x| x.name }
+ assert_equal 2, columns.length
+ assert_equal %w{ id number }.sort, columns.map { |x| x.name }
+ assert_equal [nil, nil], columns.map { |x| x.default }
+ assert_equal [true, true], columns.map { |x| x.null }
+ end
+
+ def test_columns_with_default
+ @ctx.execute <<-eosql
+ CREATE TABLE columns_with_default (
+ id integer PRIMARY KEY AUTOINCREMENT,
+ number integer default 10
+ )
+ eosql
+ column = @ctx.columns('columns_with_default').find { |x|
+ x.name == 'number'
+ }
+ assert_equal 10, column.default
+ end
+
+ def test_columns_with_not_null
+ @ctx.execute <<-eosql
+ CREATE TABLE columns_with_default (
+ id integer PRIMARY KEY AUTOINCREMENT,
+ number integer not null
+ )
+ eosql
+ column = @ctx.columns('columns_with_default').find { |x|
+ x.name == 'number'
+ }
+ assert !column.null, "column should not be null"
+ end
+
+ def test_indexes_logs
+ intercept_logs_on @ctx
+ assert_difference('@ctx.logged.length') do
+ @ctx.indexes('items')
+ end
+ assert_match(/items/, @ctx.logged.last.first)
+ end
+
+ def test_no_indexes
+ assert_equal [], @ctx.indexes('items')
+ end
+
+ def test_index
+ @ctx.add_index 'items', 'id', :unique => true, :name => 'fun'
+ index = @ctx.indexes('items').find { |idx| idx.name == 'fun' }
+
+ assert_equal 'items', index.table
+ assert index.unique, 'index is unique'
+ assert_equal ['id'], index.columns
+ end
+
+ def test_non_unique_index
+ @ctx.add_index 'items', 'id', :name => 'fun'
+ index = @ctx.indexes('items').find { |idx| idx.name == 'fun' }
+ assert !index.unique, 'index is not unique'
+ end
+
+ def test_compound_index
+ @ctx.add_index 'items', %w{ id number }, :name => 'fun'
+ index = @ctx.indexes('items').find { |idx| idx.name == 'fun' }
+ assert_equal %w{ id number }.sort, index.columns.sort
+ end
+
+ def test_primary_key
+ assert_equal 'id', @ctx.primary_key('items')
+
+ @ctx.execute <<-eosql
+ CREATE TABLE foos (
+ internet integer PRIMARY KEY AUTOINCREMENT,
+ number integer not null
+ )
+ eosql
+ assert_equal 'internet', @ctx.primary_key('foos')
+ end
+
+ def test_no_primary_key
+ @ctx.execute 'CREATE TABLE failboat (number integer not null)'
+ assert_nil @ctx.primary_key('failboat')
+ end
+
+ private
+
def assert_logged logs
+ intercept_logs_on @ctx
+ yield
+ assert_equal logs, @ctx.logged
+ end
+
+ def intercept_logs_on ctx
@ctx.extend(Module.new {
- attr_reader :logged
+ attr_accessor :logged
def log sql, name
- @logged ||= []
@logged << [sql, name]
yield
end
})
- yield
- assert_equal logs, @ctx.logged
+ @ctx.logged = []
end
end
end
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index a52cedd8c2..f1440804d2 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -549,7 +549,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert the_client.new_record?
end
- def test_find_or_create
+ def test_find_or_create_updates_size
number_of_clients = companies(:first_firm).clients.size
the_client = companies(:first_firm).clients.find_or_create_by_name("Yet another client")
assert_equal number_of_clients + 1, companies(:first_firm, :reload).clients.size
diff --git a/activerecord/test/cases/associations/has_one_through_associations_test.rb b/activerecord/test/cases/associations/has_one_through_associations_test.rb
index 178c57435b..3fcd150422 100644
--- a/activerecord/test/cases/associations/has_one_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_through_associations_test.rb
@@ -6,9 +6,12 @@ require 'models/membership'
require 'models/sponsor'
require 'models/organization'
require 'models/member_detail'
+require 'models/minivan'
+require 'models/dashboard'
+require 'models/speedometer'
class HasOneThroughAssociationsTest < ActiveRecord::TestCase
- fixtures :member_types, :members, :clubs, :memberships, :sponsors, :organizations
+ fixtures :member_types, :members, :clubs, :memberships, :sponsors, :organizations, :minivans, :dashboards, :speedometers
def setup
@member = members(:groucho)
@@ -202,4 +205,11 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase
Club.find(@club.id, :include => :sponsored_member).save!
end
end
+
+ def test_value_is_properly_quoted
+ minivan = Minivan.find('m1')
+ assert_nothing_raised do
+ minivan.dashboard
+ end
+ end
end
diff --git a/activerecord/test/cases/json_serialization_test.rb b/activerecord/test/cases/json_serialization_test.rb
index c275557da8..2bc746c0b8 100644
--- a/activerecord/test/cases/json_serialization_test.rb
+++ b/activerecord/test/cases/json_serialization_test.rb
@@ -201,4 +201,11 @@ class DatabaseConnectedJsonEncodingTest < ActiveRecord::TestCase
}
assert_equal %({"1":{"author":{"name":"David"}}}), ActiveSupport::JSON.encode(authors_hash, :only => [1, :name])
end
+
+ def test_should_be_able_to_encode_relation
+ authors_relation = Author.where(:id => [@david.id, @mary.id])
+
+ json = ActiveSupport::JSON.encode authors_relation, :only => :name
+ assert_equal '[{"author":{"name":"David"}},{"author":{"name":"Mary"}}]', json
+ end
end
diff --git a/activerecord/test/cases/relation_scoping_test.rb b/activerecord/test/cases/relation_scoping_test.rb
index 41dcdbcd37..a5a3b3ef38 100644
--- a/activerecord/test/cases/relation_scoping_test.rb
+++ b/activerecord/test/cases/relation_scoping_test.rb
@@ -364,6 +364,12 @@ class DefaultScopingTest < ActiveRecord::TestCase
assert_equal expected, received
end
+ def test_named_scope_reorders_default
+ expected = Developer.find(:all, :order => 'name DESC').collect { |dev| dev.name }
+ received = DeveloperOrderedBySalary.reordered_by_name.find(:all).collect { |dev| dev.name }
+ assert_equal expected, received
+ end
+
def test_nested_exclusive_scope
expected = Developer.find(:all, :limit => 100).collect { |dev| dev.salary }
received = DeveloperOrderedBySalary.send(:with_exclusive_scope, :find => { :limit => 100 }) do
diff --git a/activerecord/test/cases/timestamp_test.rb b/activerecord/test/cases/timestamp_test.rb
index 549c4af6b1..f765540808 100644
--- a/activerecord/test/cases/timestamp_test.rb
+++ b/activerecord/test/cases/timestamp_test.rb
@@ -25,16 +25,26 @@ class TimestampTest < ActiveRecord::TestCase
end
def test_touching_a_record_updates_its_timestamp
+ previous_salary = @developer.salary
+ @developer.salary = previous_salary + 10000
@developer.touch
assert_not_equal @previously_updated_at, @developer.updated_at
+ assert_equal previous_salary + 10000, @developer.salary
+ assert @developer.salary_changed?, 'developer salary should have changed'
+ assert @developer.changed?, 'developer should be marked as changed'
+ @developer.reload
+ assert_equal previous_salary, @developer.salary
end
def test_touching_a_different_attribute
previously_created_at = @developer.created_at
@developer.touch(:created_at)
+ assert !@developer.created_at_changed? , 'created_at should not be changed'
+ assert !@developer.changed?, 'record should not be changed'
assert_not_equal previously_created_at, @developer.created_at
+ assert_not_equal @previously_updated_at, @developer.updated_at
end
def test_saving_a_record_with_a_belongs_to_that_specifies_touching_the_parent_should_update_the_parent_updated_at
diff --git a/activerecord/test/fixtures/dashboards.yml b/activerecord/test/fixtures/dashboards.yml
new file mode 100644
index 0000000000..e75bf46e6c
--- /dev/null
+++ b/activerecord/test/fixtures/dashboards.yml
@@ -0,0 +1,3 @@
+cool_first:
+ dashboard_id: d1
+ name: my_dashboard \ No newline at end of file
diff --git a/activerecord/test/fixtures/minivans.yml b/activerecord/test/fixtures/minivans.yml
new file mode 100644
index 0000000000..e7a2ab77eb
--- /dev/null
+++ b/activerecord/test/fixtures/minivans.yml
@@ -0,0 +1,4 @@
+cool_first:
+ minivan_id: m1
+ name: my_minivan
+ speedometer_id: s1
diff --git a/activerecord/test/fixtures/speedometers.yml b/activerecord/test/fixtures/speedometers.yml
new file mode 100644
index 0000000000..6a471aba0a
--- /dev/null
+++ b/activerecord/test/fixtures/speedometers.yml
@@ -0,0 +1,4 @@
+cool_first:
+ speedometer_id: s1
+ name: my_speedometer
+ dashboard_id: d1 \ No newline at end of file
diff --git a/activerecord/test/models/dashboard.rb b/activerecord/test/models/dashboard.rb
new file mode 100644
index 0000000000..a8a25834b1
--- /dev/null
+++ b/activerecord/test/models/dashboard.rb
@@ -0,0 +1,3 @@
+class Dashboard < ActiveRecord::Base
+ set_primary_key :dashboard_id
+end \ No newline at end of file
diff --git a/activerecord/test/models/developer.rb b/activerecord/test/models/developer.rb
index de68fd7f24..c61c583c1d 100644
--- a/activerecord/test/models/developer.rb
+++ b/activerecord/test/models/developer.rb
@@ -88,6 +88,7 @@ class DeveloperOrderedBySalary < ActiveRecord::Base
self.table_name = 'developers'
default_scope :order => 'salary DESC'
scope :by_name, :order => 'name DESC'
+ scope :reordered_by_name, reorder('name DESC')
def self.all_ordered_by_name
with_scope(:find => { :order => 'name DESC' }) do
diff --git a/activerecord/test/models/minivan.rb b/activerecord/test/models/minivan.rb
new file mode 100644
index 0000000000..c753319a20
--- /dev/null
+++ b/activerecord/test/models/minivan.rb
@@ -0,0 +1,6 @@
+class Minivan < ActiveRecord::Base
+ set_primary_key :minivan_id
+
+ belongs_to :speedometer
+ has_one :dashboard, :through => :speedometer
+end \ No newline at end of file
diff --git a/activerecord/test/models/speedometer.rb b/activerecord/test/models/speedometer.rb
new file mode 100644
index 0000000000..94743eff8e
--- /dev/null
+++ b/activerecord/test/models/speedometer.rb
@@ -0,0 +1,4 @@
+class Speedometer < ActiveRecord::Base
+ set_primary_key :speedometer_id
+ belongs_to :dashboard
+end \ No newline at end of file
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index bea351b95a..641726b43f 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -164,6 +164,11 @@ ActiveRecord::Schema.define do
t.string :address_country
t.string :gps_location
end
+
+ create_table :dashboards, :force => true, :id => false do |t|
+ t.string :dashboard_id
+ t.string :name
+ end
create_table :developers, :force => true do |t|
t.string :name
@@ -290,6 +295,12 @@ ActiveRecord::Schema.define do
t.boolean :favourite
t.integer :lock_version, :default => 0
end
+
+ create_table :minivans, :force => true, :id => false do |t|
+ t.string :minivan_id
+ t.string :name
+ t.string :speedometer_id
+ end
create_table :minimalistics, :force => true do |t|
end
@@ -452,6 +463,12 @@ ActiveRecord::Schema.define do
t.string :name
t.integer :ship_id
end
+
+ create_table :speedometers, :force => true, :id => false do |t|
+ t.string :speedometer_id
+ t.string :name
+ t.string :dashboard_id
+ end
create_table :sponsors, :force => true do |t|
t.integer :club_id