aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG26
-rw-r--r--activerecord/lib/active_record/attribute_methods/primary_key.rb7
-rw-r--r--activerecord/lib/active_record/attribute_methods/read.rb6
-rw-r--r--activerecord/lib/active_record/attribute_methods/write.rb2
-rw-r--r--activerecord/lib/active_record/base.rb9
-rw-r--r--activerecord/lib/active_record/errors.rb14
-rw-r--r--activerecord/lib/active_record/fixtures.rb2
-rw-r--r--activerecord/lib/active_record/persistence.rb2
-rw-r--r--activerecord/lib/active_record/railties/databases.rake2
-rw-r--r--activerecord/lib/active_record/reflection.rb4
-rw-r--r--activerecord/lib/active_record/relation.rb6
-rw-r--r--activerecord/lib/active_record/transactions.rb2
-rw-r--r--activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb2
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb2
-rw-r--r--activerecord/test/cases/attribute_methods/read_test.rb4
-rw-r--r--activerecord/test/cases/base_test.rb4
-rw-r--r--activerecord/test/cases/primary_keys_test.rb14
-rw-r--r--activerecord/test/cases/reflection_test.rb1
-rw-r--r--activerecord/test/config.example.yml2
19 files changed, 87 insertions, 24 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index a54526dd41..f974b5d237 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,4 +1,28 @@
-Wed Sep 7 15:25:02 2011 Aaron Patterson <aaron@tenderlovemaking.com>
+*Rails 3.1.1 (unreleased)*
+
+* Add deprecation for the preload_associations method. Fixes #3022.
+
+ [Jon Leighton]
+
+* Don't require a DB connection when loading a model that uses set_primary_key. GH #2807.
+
+ [Jon Leighton]
+
+* Fix using select() with a habtm association, e.g. Person.friends.select(:name). GH #3030 and
+ #2923.
+
+ [Hendy Tanata]
+
+* Fix belongs_to polymorphic with custom primary key on target. GH #3104.
+
+ [Jon Leighton]
+
+* CollectionProxy#replace should change the DB records rather than just mutating the array.
+ Fixes #3020.
+
+ [Jon Leighton]
+
+* LRU cache in mysql and sqlite are now per-process caches.
* lib/active_record/connection_adapters/mysql_adapter.rb: LRU cache
keys are per process id.
diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb
index a404a5edd7..36d7f4ad11 100644
--- a/activerecord/lib/active_record/attribute_methods/primary_key.rb
+++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb
@@ -14,6 +14,8 @@ module ActiveRecord
# primary_key_prefix_type setting, though.
def primary_key
@primary_key ||= reset_primary_key
+ raise ActiveRecord::UnknownPrimaryKey.new(self) unless @primary_key
+ @primary_key
end
# Returns a quoted version of the primary key name, used to construct SQL statements.
@@ -29,6 +31,11 @@ module ActiveRecord
key
end
+ def primary_key? #:nodoc:
+ @primary_key ||= reset_primary_key
+ !@primary_key.nil?
+ end
+
def get_primary_key(base_name) #:nodoc:
return 'id' unless base_name && !base_name.blank?
diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb
index 4174e4da09..8566ecad14 100644
--- a/activerecord/lib/active_record/attribute_methods/read.rb
+++ b/activerecord/lib/active_record/attribute_methods/read.rb
@@ -40,7 +40,7 @@ module ActiveRecord
define_read_method(attr_name, attr_name, columns_hash[attr_name])
end
- if attr_name == primary_key && attr_name != "id"
+ if primary_key? && attr_name == primary_key && attr_name != "id"
define_read_method('id', attr_name, columns_hash[attr_name])
end
end
@@ -63,7 +63,7 @@ module ActiveRecord
cast_code = column.type_cast_code('v')
access_code = "(v=@attributes['#{attr_name}']) && #{cast_code}"
- unless attr_name.to_s == self.primary_key.to_s
+ unless primary_key? && attr_name.to_s == primary_key.to_s
access_code.insert(0, "missing_attribute('#{attr_name}', caller) unless @attributes.has_key?('#{attr_name}'); ")
end
@@ -107,7 +107,7 @@ module ActiveRecord
def _read_attribute(attr_name)
attr_name = attr_name.to_s
- attr_name = self.class.primary_key if attr_name == 'id'
+ attr_name = self.class.primary_key? && self.class.primary_key if attr_name == 'id'
value = @attributes[attr_name]
unless value.nil?
if column = column_for_attribute(attr_name)
diff --git a/activerecord/lib/active_record/attribute_methods/write.rb b/activerecord/lib/active_record/attribute_methods/write.rb
index e9cdb130db..4db6d71ba6 100644
--- a/activerecord/lib/active_record/attribute_methods/write.rb
+++ b/activerecord/lib/active_record/attribute_methods/write.rb
@@ -18,7 +18,7 @@ module ActiveRecord
end
end
- if attr_name == primary_key && attr_name != "id"
+ if primary_key? && attr_name == primary_key && attr_name != "id"
generated_attribute_methods.module_eval("alias :id= :'#{primary_key}='")
end
end
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 78159d13d4..137b4c6534 100644
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -708,7 +708,7 @@ module ActiveRecord #:nodoc:
# Returns an array of column objects for the table associated with this class.
def columns
if defined?(@primary_key)
- connection_pool.primary_keys[table_name] ||= primary_key
+ connection_pool.primary_keys[table_name] ||= @primary_key
end
connection_pool.columns[table_name]
@@ -953,7 +953,7 @@ module ActiveRecord #:nodoc:
# objects of different types from the same table.
def instantiate(record)
sti_class = find_sti_class(record[inheritance_column])
- record_id = sti_class.primary_key && record[sti_class.primary_key]
+ record_id = sti_class.primary_key? && record[sti_class.primary_key]
if ActiveRecord::IdentityMap.enabled? && record_id
if (column = sti_class.columns_hash[sti_class.primary_key]) && column.number?
@@ -1941,8 +1941,9 @@ MSG
# The primary key and inheritance column can never be set by mass-assignment for security reasons.
def self.attributes_protected_by_default
- default = [ primary_key, inheritance_column ]
- default << 'id' unless primary_key.eql? 'id'
+ default = [ inheritance_column ]
+ default << primary_key if primary_key?
+ default << 'id' unless primary_key? && primary_key == 'id'
default
end
diff --git a/activerecord/lib/active_record/errors.rb b/activerecord/lib/active_record/errors.rb
index ad7d8cd63c..8262b60f6e 100644
--- a/activerecord/lib/active_record/errors.rb
+++ b/activerecord/lib/active_record/errors.rb
@@ -169,4 +169,18 @@ module ActiveRecord
@errors = errors
end
end
+
+ # Raised when a model attempts to fetch its primary key from the database, but the table
+ # has no primary key declared.
+ class UnknownPrimaryKey < ActiveRecordError
+ attr_reader :model
+
+ def initialize(model)
+ @model = model
+ end
+
+ def message
+ "Unknown primary key for table #{model.table_name} in model #{model}."
+ end
+ end
end
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index 6f1ec7f9b3..97af15c9e8 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -622,7 +622,7 @@ module ActiveRecord
private
def primary_key_name
- @primary_key_name ||= model_class && model_class.primary_key
+ @primary_key_name ||= model_class && model_class.primary_key? && model_class.primary_key
end
def has_primary_key_column?
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index 5e65e46a7d..b5dadb929d 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -314,7 +314,7 @@ module ActiveRecord
new_id = self.class.unscoped.insert attributes_values
- self.id ||= new_id if self.class.primary_key
+ self.id ||= new_id if self.class.primary_key?
IdentityMap.add(self) if IdentityMap.enabled?
@new_record = false
diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake
index b3316fd1a2..f4a813d704 100644
--- a/activerecord/lib/active_record/railties/databases.rake
+++ b/activerecord/lib/active_record/railties/databases.rake
@@ -341,7 +341,7 @@ db_namespace = namespace :db do
namespace :schema do
desc 'Create a db/schema.rb file that can be portably used against any DB supported by AR'
- task :dump => :load_config do
+ task :dump => [:environment, :load_config] do
require 'active_record/schema_dumper'
filename = ENV['SCHEMA'] || "#{Rails.root}/db/schema.rb"
File.open(filename, "w:utf-8") do |file|
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 1929a808ed..120ff0cac6 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -212,8 +212,8 @@ module ActiveRecord
end
# klass option is necessary to support loading polymorphic associations
- def association_primary_key(klass = self.klass)
- options[:primary_key] || klass.primary_key
+ def association_primary_key(klass = nil)
+ options[:primary_key] || (klass || self.klass).primary_key
end
def active_record_primary_key
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index ecefaa633c..bf61d79a2c 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -13,7 +13,7 @@ module ActiveRecord
# These are explicitly delegated to improve performance (avoids method_missing)
delegate :to_xml, :to_yaml, :length, :collect, :map, :each, :all?, :include?, :to => :to_a
- delegate :table_name, :quoted_table_name, :primary_key, :quoted_primary_key, :connection, :column_hash,:to => :klass
+ delegate :table_name, :quoted_table_name, :primary_key, :primary_key?, :quoted_primary_key, :connection, :column_hash,:to => :klass
attr_reader :table, :klass, :loaded
attr_accessor :extensions, :default_scoped
@@ -36,7 +36,7 @@ module ActiveRecord
def insert(values)
primary_key_value = nil
- if primary_key && Hash === values
+ if primary_key? && Hash === values
primary_key_value = values[values.keys.find { |k|
k.name == primary_key
}]
@@ -70,7 +70,7 @@ module ActiveRecord
conn.insert(
im,
'SQL',
- primary_key,
+ primary_key? && primary_key,
primary_key_value,
nil,
binds)
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index ae97a3f3ca..d4870dd3f2 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -303,7 +303,7 @@ module ActiveRecord
# Save the new record state and id of a record so it can be restored later if a transaction fails.
def remember_transaction_record_state #:nodoc
@_start_transaction_state ||= {}
- @_start_transaction_state[:id] = id if has_attribute?(self.class.primary_key)
+ @_start_transaction_state[:id] = id if self.class.primary_key?
unless @_start_transaction_state.include?(:new_record)
@_start_transaction_state[:new_record] = @new_record
end
diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
index d1d02c25d5..34d90cc395 100644
--- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
@@ -651,7 +651,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
end
def test_habtm_selects_all_columns_by_default
- assert_equal Project.column_names, developers(:david).projects.first.attributes.keys
+ assert_equal Project.column_names.sort, developers(:david).projects.first.attributes.keys.sort
end
def test_habtm_respects_select_query_method
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index fdfbcbefac..cddd2a6f8c 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -486,7 +486,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
def test_default_select
- assert_equal Comment.column_names, posts(:welcome).comments.first.attributes.keys
+ assert_equal Comment.column_names.sort, posts(:welcome).comments.first.attributes.keys.sort
end
def test_select_query_method
diff --git a/activerecord/test/cases/attribute_methods/read_test.rb b/activerecord/test/cases/attribute_methods/read_test.rb
index e03ed33591..814476ce73 100644
--- a/activerecord/test/cases/attribute_methods/read_test.rb
+++ b/activerecord/test/cases/attribute_methods/read_test.rb
@@ -24,6 +24,10 @@ module ActiveRecord
def self.primary_key
end
+ def self.primary_key?
+ false
+ end
+
def self.columns
column_names.map { FakeColumn.new(name) }
end
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 12c1cfb30e..77fd1d2fad 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -97,10 +97,6 @@ class BasicsTest < ActiveRecord::TestCase
assert pk.primary, 'nick should be primary key'
end
- def test_primary_key_with_no_id
- assert_nil Edge.primary_key
- end
-
unless current_adapter?(:PostgreSQLAdapter,:OracleAdapter,:SQLServerAdapter)
def test_limit_with_comma
assert_nothing_raised do
diff --git a/activerecord/test/cases/primary_keys_test.rb b/activerecord/test/cases/primary_keys_test.rb
index 489c7d8310..58badd6266 100644
--- a/activerecord/test/cases/primary_keys_test.rb
+++ b/activerecord/test/cases/primary_keys_test.rb
@@ -5,6 +5,7 @@ require 'models/subscriber'
require 'models/movie'
require 'models/keyboard'
require 'models/mixed_case_monkey'
+require 'models/edge'
class PrimaryKeysTest < ActiveRecord::TestCase
fixtures :topics, :subscribers, :movies, :mixed_case_monkeys
@@ -161,4 +162,17 @@ class PrimaryKeysTest < ActiveRecord::TestCase
assert_equal 'foo', model.primary_key
end
+
+ def test_no_primary_key_raises
+ assert_raises(ActiveRecord::UnknownPrimaryKey) do
+ Edge.primary_key
+ end
+
+ begin
+ Edge.primary_key
+ rescue ActiveRecord::UnknownPrimaryKey => e
+ assert e.message.include?('edges')
+ assert e.message.include?('Edge')
+ end
+ end
end
diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb
index 0a48f418b1..ca9d88fbd5 100644
--- a/activerecord/test/cases/reflection_test.rb
+++ b/activerecord/test/cases/reflection_test.rb
@@ -244,6 +244,7 @@ class ReflectionTest < ActiveRecord::TestCase
# Normal association
assert_equal "id", Author.reflect_on_association(:posts).association_primary_key.to_s
assert_equal "name", Author.reflect_on_association(:essay).association_primary_key.to_s
+ assert_equal "name", Essay.reflect_on_association(:writer).association_primary_key.to_s
# Through association (uses the :primary_key option from the source reflection)
assert_equal "nick", Author.reflect_on_association(:subscribers).association_primary_key.to_s
diff --git a/activerecord/test/config.example.yml b/activerecord/test/config.example.yml
index 8c1a45430e..f450efd839 100644
--- a/activerecord/test/config.example.yml
+++ b/activerecord/test/config.example.yml
@@ -37,11 +37,13 @@ connections:
db2:
arunit:
+ adapter: ibm_db
host: localhost
username: arunit
password: arunit
database: arunit
arunit2:
+ adapter: ibm_db
host: localhost
username: arunit
password: arunit