Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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
Luciano G Panaro authored NZKoz committed
View
4 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 <tt>rank = 5</tt>.
+ # SQL fragment, such as <tt>rank = 5</tt>. Record creation from the association is scoped if a hash
+ # is used. <tt>has_one :account, :conditions => {:enabled => true}</tt> will create an enabled account with <tt>@company.create_account</tt>
+ # or <tt>@company.build_account</tt>.
# [:order]
# Specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment,
# such as <tt>last_name, first_name DESC</tt>.
View
9 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
View
18 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
View
4 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
View
2  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
Please sign in to comment.
Something went wrong with that request. Please try again.