Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add support for :primary_key option to has_one as well as has_many so…

… that a key other than the default primary key can be used for the association

Signed-off-by: Michael Koziarski <michael@koziarski.com>
  • Loading branch information...
commit afa0c7f728a8896c9ee9d932033e08a4c99dfd50 1 parent 3351d29
@bgreenlee bgreenlee authored NZKoz committed
View
3  activerecord/lib/active_record/associations.rb
@@ -759,6 +759,7 @@ def has_many(association_id, options = {}, &extension)
# * <tt>:foreign_key</tt> - 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_one+ association will use "person_id"
# as the default <tt>:foreign_key</tt>.
+ # * <tt>:primary_key</tt> - Specify the method that returns the primary key used for the association. By default this is +id+.
# * <tt>:include</tt> - Specify second-order associations that should be eager loaded when this object is loaded.
# * <tt>:as</tt> - Specifies a polymorphic interface (See <tt>belongs_to</tt>).
# * <tt>:select</tt> - By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if, for example, you want to do a join
@@ -1366,7 +1367,7 @@ def create_has_many_reflection(association_id, options, &extension)
def create_has_one_reflection(association_id, options)
options.assert_valid_keys(
- :class_name, :foreign_key, :remote, :select, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as, :readonly, :validate
+ :class_name, :foreign_key, :remote, :select, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as, :readonly, :validate, :primary_key
)
create_reflection(:has_one, association_id, options, self)
View
11 activerecord/lib/active_record/associations/has_one_association.rb
@@ -47,7 +47,16 @@ def replace(obj, dont_save = false)
return (obj.nil? ? nil : self)
end
end
-
+
+ protected
+ def owner_quoted_id
+ if @reflection.options[:primary_key]
+ quote_value(@owner.send(@reflection.options[:primary_key]))
+ else
+ @owner.quoted_id
+ end
+ end
+
private
def find_target
@reflection.klass.find(:first,
View
7 activerecord/test/cases/associations/has_one_associations_test.rb
@@ -29,6 +29,13 @@ def test_with_select
assert_equal Firm.find(1, :include => :account_with_select).account_with_select.attributes.size, 2
end
+ def test_finding_using_primary_key
+ firm = companies(:first_firm)
+ assert_equal Account.find_by_firm_id(firm.id), firm.account
+ firm.firm_id = companies(:rails_core).id
+ assert_equal accounts(:rails_core_account), firm.account_using_primary_key
+ end
+
def test_can_marshal_has_one_association_with_nil_target
firm = Firm.new
assert_nothing_raised do
View
6 activerecord/test/cases/reflection_test.rb
@@ -160,9 +160,9 @@ def test_association_reflection_in_modules
def test_reflection_of_all_associations
# FIXME these assertions bust a lot
- assert_equal 22, Firm.reflect_on_all_associations.size
- assert_equal 17, Firm.reflect_on_all_associations(:has_many).size
- assert_equal 5, Firm.reflect_on_all_associations(:has_one).size
+ assert_equal 24, Firm.reflect_on_all_associations.size
+ assert_equal 18, Firm.reflect_on_all_associations(:has_many).size
+ assert_equal 6, Firm.reflect_on_all_associations(:has_one).size
assert_equal 0, Firm.reflect_on_all_associations(:belongs_to).size
end
View
1  activerecord/test/models/company.rb
@@ -53,6 +53,7 @@ class Firm < Company
has_one :unvalidated_account, :foreign_key => "firm_id", :class_name => 'Account', :validate => false
has_one :account_with_select, :foreign_key => "firm_id", :select => "id, firm_id", :class_name=>'Account'
has_one :readonly_account, :foreign_key => "firm_id", :class_name => "Account", :readonly => true
+ has_one :account_using_primary_key, :primary_key => "firm_id", :class_name => "Account"
end
class DependentFirm < Company
Please sign in to comment.
Something went wrong with that request. Please try again.