Skip to content

Commit

Permalink
Merge pull request #6511 from frodsan/add_fixnum_string_support_for_d…
Browse files Browse the repository at this point in the history
…elete

Add support for CollectionAssociation#delete by Fixnum or String
  • Loading branch information
carlosantoniodasilva committed May 29, 2012
2 parents ef3e696 + 39f0698 commit 6f1d9d0
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 3 deletions.
13 changes: 13 additions & 0 deletions activerecord/CHANGELOG.md
@@ -1,5 +1,18 @@
## Rails 4.0.0 (unreleased) ## ## Rails 4.0.0 (unreleased) ##


* Added support to `CollectionAssociation#delete` for passing `fixnum`
or `string` values as record ids. This finds the records responding
to the `id` and executes delete on them.

class Person < ActiveRecord::Base
has_many :pets
end

person.pets.delete("1") # => [#<Pet id: 1>]
person.pets.delete(2, 3) # => [#<Pet id: 2>, #<Pet id: 3>]

*Francesco Rodriguez*

* Deprecated most of the 'dynamic finder' methods. All dynamic methods * Deprecated most of the 'dynamic finder' methods. All dynamic methods
except for `find_by_...` and `find_by_...!` are deprecated. Here's except for `find_by_...` and `find_by_...!` are deprecated. Here's
how you can rewrite the code: how you can rewrite the code:
Expand Down
Expand Up @@ -230,6 +230,7 @@ def delete(*records)
delete_records(:all, dependent) delete_records(:all, dependent)
end end
else else
records = find(records) if records.any? { |record| record.kind_of?(Fixnum) || record.kind_of?(String) }
delete_or_destroy(records, dependent) delete_or_destroy(records, dependent)
end end
end end
Expand Down
26 changes: 26 additions & 0 deletions activerecord/lib/active_record/associations/collection_proxy.rb
Expand Up @@ -469,6 +469,8 @@ class CollectionProxy < Relation
# #
# :call-seq: # :call-seq:
# delete(*records) # delete(*records)
# delete(*fixnum_ids)
# delete(*string_ids)
# #
# Deletes the +records+ supplied and removes them from the collection. For # Deletes the +records+ supplied and removes them from the collection. For
# +has_many+ associations, the deletion is done according to the strategy # +has_many+ associations, the deletion is done according to the strategy
Expand Down Expand Up @@ -560,6 +562,30 @@ class CollectionProxy < Relation
# #
# Pet.find(1) # Pet.find(1)
# # => ActiveRecord::RecordNotFound: Couldn't find Pet with id=1 # # => ActiveRecord::RecordNotFound: Couldn't find Pet with id=1
#
# You can pass +Fixnum+ or +String+ values, it finds the records
# responding to the +id+ and executes delete on them.
#
# class Person < ActiveRecord::Base
# has_many :pets
# end
#
# person.pets.size # => 3
# person.pets
# # => [
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# # #<Pet id: 2, name: "Spook", person_id: 1>,
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# # ]
#
# person.pets.delete("1")
# # => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
#
# person.pets.delete(2, 3)
# # => [
# # #<Pet id: 2, name: "Spook", person_id: 1>,
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# # ]


## ##
# :method: destroy # :method: destroy
Expand Down
20 changes: 17 additions & 3 deletions activerecord/test/cases/associations/has_many_associations_test.rb
Expand Up @@ -936,10 +936,24 @@ def test_deleting_a_item_which_is_not_in_the_collection
assert_equal 2, summit.client_of assert_equal 2, summit.client_of
end end


def test_deleting_type_mismatch def test_deleting_by_fixnum_id
david = Developer.find(1) david = Developer.find(1)
david.projects.reload
assert_raise(ActiveRecord::AssociationTypeMismatch) { david.projects.delete(1) } assert_difference 'david.projects.count', -1 do
assert_equal 1, david.projects.delete(1).size
end

assert_equal 1, david.projects.size
end

def test_deleting_by_string_id
david = Developer.find(1)

assert_difference 'david.projects.count', -1 do
assert_equal 1, david.projects.delete('1').size
end

assert_equal 1, david.projects.size
end end


def test_deleting_self_type_mismatch def test_deleting_self_type_mismatch
Expand Down

0 comments on commit 6f1d9d0

Please sign in to comment.