Skip to content
This repository
Browse code

Make has_one with :conditions hash scope build or creation of the ass…

…ociated object with those conditions

Signed-off-by: Michael Koziarski <michael@koziarski.com>
[#3088 state:committed]
  • Loading branch information...
commit 4168f876238982d0d584006f50188071928a8b7f 1 parent d48ebea
authored September 26, 2009 NZKoz committed September 28, 2009
4  activerecord/lib/active_record/associations.rb
@@ -938,7 +938,9 @@ def has_many(association_id, options = {}, &extension)
938 938
       #   if the real class name is Person, you'll have to specify it with this option.
939 939
       # [:conditions]
940 940
       #   Specify the conditions that the associated object must meet in order to be included as a +WHERE+
941  
-      #   SQL fragment, such as <tt>rank = 5</tt>.
  941
+      #   SQL fragment, such as <tt>rank = 5</tt>. Record creation from the association is scoped if a hash
  942
+      #   is used. <tt>has_one :account, :conditions => {:enabled => true}</tt> will create an enabled account with <tt>@company.create_account</tt>
  943
+      #   or <tt>@company.build_account</tt>.
942 944
       # [:order]
943 945
       #   Specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment,
944 946
       #   such as <tt>last_name, first_name DESC</tt>.
9  activerecord/lib/active_record/associations/has_one_association.rb
@@ -8,18 +8,21 @@ def initialize(owner, reflection)
8 8
 
9 9
       def create(attrs = {}, replace_existing = true)
10 10
         new_record(replace_existing) do |reflection|
  11
+          attrs = merge_with_conditions(attrs)
11 12
           reflection.create_association(attrs)
12 13
         end
13 14
       end
14 15
 
15 16
       def create!(attrs = {}, replace_existing = true)
16 17
         new_record(replace_existing) do |reflection|
  18
+          attrs = merge_with_conditions(attrs)
17 19
           reflection.create_association!(attrs)
18 20
         end
19 21
       end
20 22
 
21 23
       def build(attrs = {}, replace_existing = true)
22 24
         new_record(replace_existing) do |reflection|
  25
+          attrs = merge_with_conditions(attrs)
23 26
           reflection.build_association(attrs)
24 27
         end
25 28
       end
@@ -128,6 +131,12 @@ def we_can_set_the_inverse_on_this?(record)
128 131
           inverse = @reflection.inverse_of
129 132
           return !inverse.nil?
130 133
         end
  134
+
  135
+        def merge_with_conditions(attrs={})
  136
+          attrs ||= {}
  137
+          attrs.update(@reflection.options[:conditions]) if @reflection.options[:conditions].is_a?(Hash)
  138
+          attrs
  139
+        end
131 140
     end
132 141
   end
133 142
 end
18  activerecord/test/cases/associations/has_one_associations_test.rb
@@ -315,4 +315,22 @@ def test_save_of_record_with_loaded_has_one
315 315
       Firm.find(@firm.id, :include => :account).save!
316 316
     end
317 317
   end
  318
+
  319
+  def test_build_respects_hash_condition
  320
+    account = companies(:first_firm).build_account_limit_500_with_hash_conditions
  321
+    assert account.save
  322
+    assert_equal 500, account.credit_limit
  323
+  end
  324
+
  325
+  def test_create_respects_hash_condition
  326
+    account = companies(:first_firm).create_account_limit_500_with_hash_conditions
  327
+    assert       !account.new_record?
  328
+    assert_equal 500, account.credit_limit
  329
+  end
  330
+
  331
+  def test_create!_respects_hash_condition
  332
+    account = companies(:first_firm).create_account_limit_500_with_hash_conditions!
  333
+    assert       !account.new_record?
  334
+    assert_equal 500, account.credit_limit
  335
+  end
318 336
 end
4  activerecord/test/cases/reflection_test.rb
@@ -176,9 +176,9 @@ def test_association_reflection_in_modules
176 176
 
177 177
   def test_reflection_of_all_associations
178 178
     # FIXME these assertions bust a lot
179  
-    assert_equal 35, Firm.reflect_on_all_associations.size
  179
+    assert_equal 36, Firm.reflect_on_all_associations.size
180 180
     assert_equal 26, Firm.reflect_on_all_associations(:has_many).size
181  
-    assert_equal 9, Firm.reflect_on_all_associations(:has_one).size
  181
+    assert_equal 10, Firm.reflect_on_all_associations(:has_one).size
182 182
     assert_equal 0, Firm.reflect_on_all_associations(:belongs_to).size
183 183
   end
184 184
 
2  activerecord/test/models/company.rb
@@ -81,6 +81,8 @@ class Firm < Company
81 81
   has_one :account_using_foreign_and_primary_keys, :foreign_key => "firm_name", :primary_key => "name", :class_name => "Account"
82 82
   has_one :deletable_account, :foreign_key => "firm_id", :class_name => "Account", :dependent => :delete
83 83
   
  84
+  has_one :account_limit_500_with_hash_conditions, :foreign_key => "firm_id", :class_name => "Account", :conditions => { :credit_limit => 500 }
  85
+
84 86
   has_one :unautosaved_account, :foreign_key => "firm_id", :class_name => 'Account', :autosave => false
85 87
   has_many :accounts
86 88
   has_many :unautosaved_accounts, :foreign_key => "firm_id", :class_name => 'Account', :autosave => false

0 notes on commit 4168f87

Please sign in to comment.
Something went wrong with that request. Please try again.