diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 266a52d612ebc34de8ee8d6a0784b03896af684b..497115e4ff2d9d07b1534a0f6deb07deb48dd8ab 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -938,7 +938,9 @@ def has_many(association_id, options = {}, &extension) # if the real class name is Person, you'll have to specify it with this option. # [:conditions] # Specify the conditions that the associated object must meet in order to be included as a +WHERE+ - # SQL fragment, such as rank = 5. + # SQL fragment, such as rank = 5. Record creation from the association is scoped if a hash + # is used. has_one :account, :conditions => {:enabled => true} will create an enabled account with @company.create_account + # or @company.build_account. # [:order] # Specify the order in which the associated objects are returned as an ORDER BY SQL fragment, # such as last_name, first_name DESC. diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb index c2568d0c0ce571c9951f6e238dd0f201375c98e2..b85a40b2e5fe6b887f40b1b105e88a39d542f74b 100644 --- a/activerecord/lib/active_record/associations/has_one_association.rb +++ b/activerecord/lib/active_record/associations/has_one_association.rb @@ -8,18 +8,21 @@ def initialize(owner, reflection) def create(attrs = {}, replace_existing = true) new_record(replace_existing) do |reflection| + attrs = merge_with_conditions(attrs) reflection.create_association(attrs) end end def create!(attrs = {}, replace_existing = true) new_record(replace_existing) do |reflection| + attrs = merge_with_conditions(attrs) reflection.create_association!(attrs) end end def build(attrs = {}, replace_existing = true) new_record(replace_existing) do |reflection| + attrs = merge_with_conditions(attrs) reflection.build_association(attrs) end end @@ -128,6 +131,12 @@ def we_can_set_the_inverse_on_this?(record) inverse = @reflection.inverse_of return !inverse.nil? end + + def merge_with_conditions(attrs={}) + attrs ||= {} + attrs.update(@reflection.options[:conditions]) if @reflection.options[:conditions].is_a?(Hash) + attrs + end end end end diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb index cdac86a3b94972a27359196c520912691d57f0d4..289c89d1e25695de7a8eda1c9631685ebb15c0fa 100644 --- a/activerecord/test/cases/associations/has_one_associations_test.rb +++ b/activerecord/test/cases/associations/has_one_associations_test.rb @@ -315,4 +315,22 @@ def test_save_of_record_with_loaded_has_one Firm.find(@firm.id, :include => :account).save! end end + + def test_build_respects_hash_condition + account = companies(:first_firm).build_account_limit_500_with_hash_conditions + assert account.save + assert_equal 500, account.credit_limit + end + + def test_create_respects_hash_condition + account = companies(:first_firm).create_account_limit_500_with_hash_conditions + assert !account.new_record? + assert_equal 500, account.credit_limit + end + + def test_create!_respects_hash_condition + account = companies(:first_firm).create_account_limit_500_with_hash_conditions! + assert !account.new_record? + assert_equal 500, account.credit_limit + end end diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb index 0eb2da720ee3ddb134be5ed3c3c6a876991629bc..f3ed8ccd8ddc0ee053911d4e0d623ab438e6e475 100644 --- a/activerecord/test/cases/reflection_test.rb +++ b/activerecord/test/cases/reflection_test.rb @@ -176,9 +176,9 @@ def test_association_reflection_in_modules def test_reflection_of_all_associations # FIXME these assertions bust a lot - assert_equal 35, Firm.reflect_on_all_associations.size + assert_equal 36, Firm.reflect_on_all_associations.size assert_equal 26, Firm.reflect_on_all_associations(:has_many).size - assert_equal 9, Firm.reflect_on_all_associations(:has_one).size + assert_equal 10, Firm.reflect_on_all_associations(:has_one).size assert_equal 0, Firm.reflect_on_all_associations(:belongs_to).size end diff --git a/activerecord/test/models/company.rb b/activerecord/test/models/company.rb index b1a3930e4ee2af66f7fb5de074ef33229f5cf524..469f5399ae65af46d86efca42e9b35f468523fbf 100644 --- a/activerecord/test/models/company.rb +++ b/activerecord/test/models/company.rb @@ -81,6 +81,8 @@ class Firm < Company has_one :account_using_foreign_and_primary_keys, :foreign_key => "firm_name", :primary_key => "name", :class_name => "Account" has_one :deletable_account, :foreign_key => "firm_id", :class_name => "Account", :dependent => :delete + has_one :account_limit_500_with_hash_conditions, :foreign_key => "firm_id", :class_name => "Account", :conditions => { :credit_limit => 500 } + has_one :unautosaved_account, :foreign_key => "firm_id", :class_name => 'Account', :autosave => false has_many :accounts has_many :unautosaved_accounts, :foreign_key => "firm_id", :class_name => 'Account', :autosave => false