Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Set attributes properly for model built from association with conditi…
…ons [#5562 state:resolved]

Signed-off-by: Santiago Pastorino <santiago@wyeworks.com>
  • Loading branch information
marklazz authored and spastorino committed Sep 28, 2010
1 parent 1ef2b47 commit cdfd013
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 10 deletions.
17 changes: 9 additions & 8 deletions activerecord/lib/active_record/base.rb
Expand Up @@ -1384,10 +1384,7 @@ def initialize(attributes = nil)

ensure_proper_type

if scope = self.class.send(:current_scoped_methods)
create_with = scope.scope_for_create
create_with.each { |att,value| self.send("#{att}=", value) } if create_with
end
populate_with_current_scope_attributes
self.attributes = attributes unless attributes.nil?

result = yield self if block_given?
Expand Down Expand Up @@ -1416,10 +1413,7 @@ def initialize_copy(other)
@new_record = true
ensure_proper_type

if scope = self.class.send(:current_scoped_methods)
create_with = scope.scope_for_create
create_with.each { |att,value| self.send("#{att}=", value) } if create_with
end
populate_with_current_scope_attributes
end

# Returns a String, which Action Pack uses for constructing an URL to this
Expand Down Expand Up @@ -1808,6 +1802,13 @@ def object_from_yaml(string)
return string unless string.is_a?(String) && string =~ /^---/
YAML::load(string) rescue string
end

def populate_with_current_scope_attributes
if scope = self.class.send(:current_scoped_methods)
create_with = scope.scope_for_create
create_with.each { |att,value| self.respond_to?(:"#{att}=") && self.send("#{att}=", value) } if create_with
end
end
end

Base.class_eval do
Expand Down
6 changes: 5 additions & 1 deletion activerecord/lib/active_record/relation.rb
Expand Up @@ -326,7 +326,11 @@ def where_values_hash

def scope_for_create
@scope_for_create ||= begin
@create_with_value || where_values_hash
if @create_with_value
@create_with_value.reverse_merge(where_values_hash || {})
else
where_values_hash
end
end
end

Expand Down
Expand Up @@ -474,4 +474,9 @@ def test_invalid_belongs_to_dependent_option_restrict_raises_exception
Author.belongs_to :special_author_address, :dependent => :restrict
end
end

def test_attributes_are_being_set_when_initialized_from_belongs_to_association_with_where_clause
new_firm = accounts(:signals37).build_firm(:name => 'Apple')
assert_equal new_firm.name, "Apple"
end
end
Expand Up @@ -848,4 +848,14 @@ def test_caching_of_columns
assert_queries(0) { david.projects.columns; david.projects.columns }
end

def test_attributes_are_being_set_when_initialized_from_habm_association_with_where_clause
new_developer = projects(:action_controller).developers.where(:name => "Marcelo").build
assert_equal new_developer.name, "Marcelo"
end

def test_attributes_are_being_set_when_initialized_from_habm_association_with_multiple_where_clauses
new_developer = projects(:action_controller).developers.where(:name => "Marcelo").where(:salary => 90_000).build
assert_equal new_developer.name, "Marcelo"
assert_equal new_developer.salary, 90_000
end
end
12 changes: 12 additions & 0 deletions activerecord/test/cases/associations/has_many_associations_test.rb
Expand Up @@ -1255,4 +1255,16 @@ class NullifyModel < ActiveRecord::Base
end
EOF
end

def test_attributes_are_being_set_when_initialized_from_has_many_association_with_where_clause
new_comment = posts(:welcome).comments.where(:body => "Some content").build
assert_equal new_comment.body, "Some content"
end

def test_attributes_are_being_set_when_initialized_from_has_many_association_with_multiple_where_clauses
new_comment = posts(:welcome).comments.where(:body => "Some content").where(:type => 'SpecialComment').build
assert_equal new_comment.body, "Some content"
assert_equal new_comment.type, "SpecialComment"
assert_equal new_comment.post_id, posts(:welcome).id
end
end
Expand Up @@ -421,4 +421,18 @@ def test_collection_singular_ids_setter_raises_exception_when_invalid_ids_set
assert_raises(ActiveRecord::RecordNotFound) {company.developer_ids= ids}
end

def test_build_a_model_from_hm_through_association_with_where_clause
assert_nothing_raised { books(:awdr).subscribers.where(:nick => "marklazz").build }
end

def test_attributes_are_being_set_when_initialized_from_hm_through_association_with_where_clause
new_subscriber = books(:awdr).subscribers.where(:nick => "marklazz").build
assert_equal new_subscriber.nick, "marklazz"
end

def test_attributes_are_being_set_when_initialized_from_hm_through_association_with_multiple_where_clauses
new_subscriber = books(:awdr).subscribers.where(:nick => "marklazz").where(:name => 'Marcelo Giorgi').build
assert_equal new_subscriber.nick, "marklazz"
assert_equal new_subscriber.name, "Marcelo Giorgi"
end
end
Expand Up @@ -326,4 +326,9 @@ def test_create_respects_hash_condition
assert !account.new_record?
assert_equal 500, account.credit_limit
end

def test_attributes_are_being_set_when_initialized_from_has_one_association_with_where_clause
new_account = companies(:first_firm).build_account(:firm_name => 'Account')
assert_equal new_account.firm_name, "Account"
end
end
2 changes: 1 addition & 1 deletion activerecord/test/cases/method_scoping_test.rb
Expand Up @@ -219,7 +219,7 @@ def test_scoped_create
new_comment = nil

VerySpecialComment.send(:with_scope, :create => { :post_id => 1 }) do
assert_equal({:post_id => 1}, VerySpecialComment.scoped.send(:scope_for_create))
assert_equal({:post_id => 1, :type => 'VerySpecialComment' }, VerySpecialComment.scoped.send(:scope_for_create))
new_comment = VerySpecialComment.create :body => "Wonderful world"
end

Expand Down

0 comments on commit cdfd013

Please sign in to comment.