mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Add has_many :primary_key option to allow setting the primary key on a has many association
Signed-off-by: Michael Koziarski <michael@koziarski.com>
This commit is contained in:
parent
1d8623b42f
commit
3351d29970
6 changed files with 19 additions and 2 deletions
|
@ -663,6 +663,7 @@ module ActiveRecord
|
|||
# * <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_many+ 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>:dependent</tt> - If set to <tt>:destroy</tt> all the associated objects are destroyed
|
||||
# alongside this object by calling their +destroy+ method. If set to <tt>:delete_all</tt> all associated
|
||||
# objects are deleted *without* calling their +destroy+ method. If set to <tt>:nullify</tt> all associated
|
||||
|
@ -678,7 +679,7 @@ module ActiveRecord
|
|||
# * <tt>:limit</tt> - An integer determining the limit on the number of rows that should be returned.
|
||||
# * <tt>:offset</tt> - An integer determining the offset from where the rows should be fetched. So at 5, it would skip the first 4 rows.
|
||||
# * <tt>:select</tt> - By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if you, for example, want to do a join
|
||||
# but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will rise an error.
|
||||
# but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will raise an error.
|
||||
# * <tt>:as</tt> - Specifies a polymorphic interface (See <tt>belongs_to</tt>).
|
||||
# * <tt>:through</tt> - Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt> and <tt>:foreign_key</tt>
|
||||
# are ignored, as the association uses the source reflection. You can only use a <tt>:through</tt> query through a <tt>belongs_to</tt>
|
||||
|
@ -1347,7 +1348,7 @@ module ActiveRecord
|
|||
|
||||
def create_has_many_reflection(association_id, options, &extension)
|
||||
options.assert_valid_keys(
|
||||
:class_name, :table_name, :foreign_key,
|
||||
:class_name, :table_name, :foreign_key, :primary_key,
|
||||
:dependent,
|
||||
:select, :conditions, :include, :order, :group, :limit, :offset,
|
||||
:as, :through, :source, :source_type,
|
||||
|
|
|
@ -19,6 +19,14 @@ module ActiveRecord
|
|||
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
|
||||
|
||||
def count_records
|
||||
count = if has_cached_counter?
|
||||
@owner.send(:read_attribute, cached_counter_attribute_name)
|
||||
|
|
|
@ -129,6 +129,10 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|||
assert_equal "Microsoft", Firm.find(:first).clients_like_ms_with_hash_conditions.first.name
|
||||
end
|
||||
|
||||
def test_finding_using_primary_key
|
||||
assert_equal "Summit", Firm.find(:first).clients_using_primary_key.first.name
|
||||
end
|
||||
|
||||
def test_finding_using_sql
|
||||
firm = Firm.find(:first)
|
||||
first_client = firm.clients_using_sql.first
|
||||
|
|
1
activerecord/test/fixtures/companies.yml
vendored
1
activerecord/test/fixtures/companies.yml
vendored
|
@ -5,6 +5,7 @@ first_client:
|
|||
client_of: 2
|
||||
name: Summit
|
||||
ruby_type: Client
|
||||
firm_name: 37signals
|
||||
|
||||
first_firm:
|
||||
id: 1
|
||||
|
|
|
@ -46,6 +46,8 @@ class Firm < Company
|
|||
has_many :clients_using_finder_sql, :class_name => "Client", :finder_sql => 'SELECT * FROM companies WHERE 1=1'
|
||||
has_many :plain_clients, :class_name => 'Client'
|
||||
has_many :readonly_clients, :class_name => 'Client', :readonly => true
|
||||
has_many :clients_using_primary_key, :class_name => 'Client',
|
||||
:primary_key => 'name', :foreign_key => 'firm_name'
|
||||
|
||||
has_one :account, :foreign_key => "firm_id", :dependent => :destroy, :validate => true
|
||||
has_one :unvalidated_account, :foreign_key => "firm_id", :class_name => 'Account', :validate => false
|
||||
|
|
|
@ -102,6 +102,7 @@ ActiveRecord::Schema.define do
|
|||
t.string :type
|
||||
t.string :ruby_type
|
||||
t.integer :firm_id
|
||||
t.string :firm_name
|
||||
t.string :name
|
||||
t.integer :client_of
|
||||
t.integer :rating, :default => 1
|
||||
|
|
Loading…
Reference in a new issue