mirror of
https://github.com/github/rails.git
synced 2026-01-28 07:48:00 -05:00
Added :select option to has_one and belongs_to, remove unused :order option on belongs_to.
Signed-off-by: Michael Koziarski <michael@koziarski.com> [#241 state:resolved]
This commit is contained in:
committed by
Michael Koziarski
parent
5b8d0f134a
commit
8d0b4fa39f
16
activerecord/lib/active_record/associations.rb
Normal file → Executable file
16
activerecord/lib/active_record/associations.rb
Normal file → Executable file
@@ -667,7 +667,7 @@ module ActiveRecord
|
|||||||
# * <tt>:limit</tt> - An integer determining the limit on the number of rows that should be returned.
|
# * <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>: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
|
# * <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.
|
# but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will rise an error.
|
||||||
# * <tt>:as</tt> - Specifies a polymorphic interface (See <tt>belongs_to</tt>).
|
# * <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>
|
# * <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>
|
# are ignored, as the association uses the source reflection. You can only use a <tt>:through</tt> query through a <tt>belongs_to</tt>
|
||||||
@@ -747,6 +747,8 @@ module ActiveRecord
|
|||||||
# as the default <tt>:foreign_key</tt>.
|
# as the default <tt>:foreign_key</tt>.
|
||||||
# * <tt>:include</tt> - Specify second-order associations that should be eager loaded when this object is loaded.
|
# * <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>: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
|
||||||
|
# but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will raise an error.
|
||||||
# * <tt>:through</tt>: Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt> and <tt>:foreign_key</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
|
# are ignored, as the association uses the source reflection. You can only use a <tt>:through</tt> query through a
|
||||||
# <tt>has_one</tt> or <tt>belongs_to</tt> association on the join model.
|
# <tt>has_one</tt> or <tt>belongs_to</tt> association on the join model.
|
||||||
@@ -821,8 +823,8 @@ module ActiveRecord
|
|||||||
# if the real class name is Person, you'll have to specify it with this option.
|
# if the real class name is Person, you'll have to specify it with this option.
|
||||||
# * <tt>:conditions</tt> - Specify the conditions that the associated object must meet in order to be included as a +WHERE+
|
# * <tt>:conditions</tt> - Specify the conditions that the associated object must meet in order to be included as a +WHERE+
|
||||||
# SQL fragment, such as <tt>authorized = 1</tt>.
|
# SQL fragment, such as <tt>authorized = 1</tt>.
|
||||||
# * <tt>:order</tt> - Specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment,
|
# * <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
|
||||||
# such as <tt>last_name, first_name DESC</tt>.
|
# but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will raise an error.
|
||||||
# * <tt>:foreign_key</tt> - Specify the foreign key used for the association. By default this is guessed to be the name
|
# * <tt>:foreign_key</tt> - Specify the foreign key used for the association. By default this is guessed to be the name
|
||||||
# of the association with an "_id" suffix. So a class that defines a <tt>belongs_to :person</tt> association will use
|
# of the association with an "_id" suffix. So a class that defines a <tt>belongs_to :person</tt> association will use
|
||||||
# "person_id" as the default <tt>:foreign_key</tt>. Similarly, <tt>belongs_to :favorite_person, :class_name => "Person"</tt>
|
# "person_id" as the default <tt>:foreign_key</tt>. Similarly, <tt>belongs_to :favorite_person, :class_name => "Person"</tt>
|
||||||
@@ -1011,7 +1013,7 @@ module ActiveRecord
|
|||||||
# * <tt>:limit</tt> - An integer determining the limit on the number of rows that should be returned.
|
# * <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>: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, for example, you want to do a join
|
# * <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
|
||||||
# but not include the joined columns.
|
# but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will raise an error.
|
||||||
# * <tt>:readonly</tt> - If true, all the associated objects are readonly through the association.
|
# * <tt>:readonly</tt> - If true, all the associated objects are readonly through the association.
|
||||||
#
|
#
|
||||||
# Option examples:
|
# Option examples:
|
||||||
@@ -1341,7 +1343,7 @@ module ActiveRecord
|
|||||||
|
|
||||||
def create_has_one_reflection(association_id, options)
|
def create_has_one_reflection(association_id, options)
|
||||||
options.assert_valid_keys(
|
options.assert_valid_keys(
|
||||||
:class_name, :foreign_key, :remote, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as, :readonly
|
:class_name, :foreign_key, :remote, :select, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as, :readonly
|
||||||
)
|
)
|
||||||
|
|
||||||
create_reflection(:has_one, association_id, options, self)
|
create_reflection(:has_one, association_id, options, self)
|
||||||
@@ -1349,14 +1351,14 @@ module ActiveRecord
|
|||||||
|
|
||||||
def create_has_one_through_reflection(association_id, options)
|
def create_has_one_through_reflection(association_id, options)
|
||||||
options.assert_valid_keys(
|
options.assert_valid_keys(
|
||||||
:class_name, :foreign_key, :remote, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as, :through, :source, :source_type
|
:class_name, :foreign_key, :remote, :select, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as, :through, :source, :source_type
|
||||||
)
|
)
|
||||||
create_reflection(:has_one, association_id, options, self)
|
create_reflection(:has_one, association_id, options, self)
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_belongs_to_reflection(association_id, options)
|
def create_belongs_to_reflection(association_id, options)
|
||||||
options.assert_valid_keys(
|
options.assert_valid_keys(
|
||||||
:class_name, :foreign_key, :foreign_type, :remote, :conditions, :order, :include, :dependent,
|
:class_name, :foreign_key, :foreign_type, :remote, :select, :conditions, :include, :dependent,
|
||||||
:counter_cache, :extend, :polymorphic, :readonly
|
:counter_cache, :extend, :polymorphic, :readonly
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
5
activerecord/lib/active_record/associations/belongs_to_association.rb
Normal file → Executable file
5
activerecord/lib/active_record/associations/belongs_to_association.rb
Normal file → Executable file
@@ -42,10 +42,11 @@ module ActiveRecord
|
|||||||
private
|
private
|
||||||
def find_target
|
def find_target
|
||||||
@reflection.klass.find(
|
@reflection.klass.find(
|
||||||
@owner[@reflection.primary_key_name],
|
@owner[@reflection.primary_key_name],
|
||||||
|
:select => @reflection.options[:select],
|
||||||
:conditions => conditions,
|
:conditions => conditions,
|
||||||
:include => @reflection.options[:include],
|
:include => @reflection.options[:include],
|
||||||
:readonly => @reflection.options[:readonly]
|
:readonly => @reflection.options[:readonly]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
5
activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb
Normal file → Executable file
5
activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb
Normal file → Executable file
@@ -29,12 +29,13 @@ module ActiveRecord
|
|||||||
|
|
||||||
if @reflection.options[:conditions]
|
if @reflection.options[:conditions]
|
||||||
association_class.find(
|
association_class.find(
|
||||||
@owner[@reflection.primary_key_name],
|
@owner[@reflection.primary_key_name],
|
||||||
|
:select => @reflection.options[:select],
|
||||||
:conditions => conditions,
|
:conditions => conditions,
|
||||||
:include => @reflection.options[:include]
|
:include => @reflection.options[:include]
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
association_class.find(@owner[@reflection.primary_key_name], :include => @reflection.options[:include])
|
association_class.find(@owner[@reflection.primary_key_name], :select => @reflection.options[:select], :include => @reflection.options[:include])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
5
activerecord/lib/active_record/associations/has_one_association.rb
Normal file → Executable file
5
activerecord/lib/active_record/associations/has_one_association.rb
Normal file → Executable file
@@ -51,10 +51,11 @@ module ActiveRecord
|
|||||||
private
|
private
|
||||||
def find_target
|
def find_target
|
||||||
@reflection.klass.find(:first,
|
@reflection.klass.find(:first,
|
||||||
:conditions => @finder_sql,
|
:conditions => @finder_sql,
|
||||||
|
:select => @reflection.options[:select],
|
||||||
:order => @reflection.options[:order],
|
:order => @reflection.options[:order],
|
||||||
:include => @reflection.options[:include],
|
:include => @reflection.options[:include],
|
||||||
:readonly => @reflection.options[:readonly]
|
:readonly => @reflection.options[:readonly]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
5
activerecord/test/cases/associations/belongs_to_associations_test.rb
Normal file → Executable file
5
activerecord/test/cases/associations/belongs_to_associations_test.rb
Normal file → Executable file
@@ -92,6 +92,11 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|||||||
assert_not_nil Company.find(3).firm_with_condition, "Microsoft should have a firm"
|
assert_not_nil Company.find(3).firm_with_condition, "Microsoft should have a firm"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_with_select
|
||||||
|
assert_equal Company.find(2).firm_with_select.attributes.size, 1
|
||||||
|
assert_equal Company.find(2, :include => :firm_with_select ).firm_with_select.attributes.size, 1
|
||||||
|
end
|
||||||
|
|
||||||
def test_belongs_to_counter
|
def test_belongs_to_counter
|
||||||
debate = Topic.create("title" => "debate")
|
debate = Topic.create("title" => "debate")
|
||||||
assert_equal 0, debate.send(:read_attribute, "replies_count"), "No replies yet"
|
assert_equal 0, debate.send(:read_attribute, "replies_count"), "No replies yet"
|
||||||
|
|||||||
5
activerecord/test/cases/associations/has_one_associations_test.rb
Normal file → Executable file
5
activerecord/test/cases/associations/has_one_associations_test.rb
Normal file → Executable file
@@ -24,6 +24,11 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
|
|||||||
assert_queries(0) { firms.each(&:account) }
|
assert_queries(0) { firms.each(&:account) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_with_select
|
||||||
|
assert_equal Firm.find(1).account_with_select.attributes.size, 2
|
||||||
|
assert_equal Firm.find(1, :include => :account_with_select).attributes.size, 2
|
||||||
|
end
|
||||||
|
|
||||||
def test_can_marshal_has_one_association_with_nil_target
|
def test_can_marshal_has_one_association_with_nil_target
|
||||||
firm = Firm.new
|
firm = Firm.new
|
||||||
assert_nothing_raised do
|
assert_nothing_raised do
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ class Firm < Company
|
|||||||
has_many :readonly_clients, :class_name => 'Client', :readonly => true
|
has_many :readonly_clients, :class_name => 'Client', :readonly => true
|
||||||
|
|
||||||
has_one :account, :foreign_key => "firm_id", :dependent => :destroy
|
has_one :account, :foreign_key => "firm_id", :dependent => :destroy
|
||||||
|
has_one :account_with_select, :foreign_key => "firm_id", :select => "id, firm_id"
|
||||||
has_one :readonly_account, :foreign_key => "firm_id", :class_name => "Account", :readonly => true
|
has_one :readonly_account, :foreign_key => "firm_id", :class_name => "Account", :readonly => true
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -64,6 +65,7 @@ end
|
|||||||
class Client < Company
|
class Client < Company
|
||||||
belongs_to :firm, :foreign_key => "client_of"
|
belongs_to :firm, :foreign_key => "client_of"
|
||||||
belongs_to :firm_with_basic_id, :class_name => "Firm", :foreign_key => "firm_id"
|
belongs_to :firm_with_basic_id, :class_name => "Firm", :foreign_key => "firm_id"
|
||||||
|
belongs_to :firm_with_select, :class_name => "Firm", :foreign_key => "firm_id", :select => "id"
|
||||||
belongs_to :firm_with_other_name, :class_name => "Firm", :foreign_key => "client_of"
|
belongs_to :firm_with_other_name, :class_name => "Firm", :foreign_key => "client_of"
|
||||||
belongs_to :firm_with_condition, :class_name => "Firm", :foreign_key => "client_of", :conditions => ["1 = ?", 1]
|
belongs_to :firm_with_condition, :class_name => "Firm", :foreign_key => "client_of", :conditions => ["1 = ?", 1]
|
||||||
belongs_to :readonly_firm, :class_name => "Firm", :foreign_key => "firm_id", :readonly => true
|
belongs_to :readonly_firm, :class_name => "Firm", :foreign_key => "firm_id", :readonly => true
|
||||||
|
|||||||
Reference in New Issue
Block a user